From 99bcad0e21b64eca5815c69a2c5f541eb577e89a Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 10 Feb 2022 19:05:30 -0800 Subject: [PATCH 01/35] Serialization interface (#192) --- bootstrap/src/build_buildcc.cpp | 2 +- .../lib/target/cmake/common_target_src.cmake | 13 +- .../include/target/base/generator_loader.h | 67 ------- .../include/target/base/target_loader.h | 145 -------------- .../include/target/base/target_storer.h | 60 ------ .../lib/target/include/target/common/path.h | 68 +++---- buildcc/lib/target/include/target/generator.h | 23 ++- .../target/interface/builder_interface.h | 3 - .../target/interface/loader_interface.h | 40 ---- .../interface/serialization_interface.h | 76 ++++++++ .../include/target/private/schema_util.h | 23 ++- .../serialization/generator_serialization.h | 58 ++++++ .../serialization/target_serialization.h | 85 ++++++++ buildcc/lib/target/include/target/target.h | 22 +-- .../lib/target/include/target/target_info.h | 21 +- buildcc/lib/target/src/api/deps_api.cpp | 4 +- buildcc/lib/target/src/api/flag_api.cpp | 16 +- buildcc/lib/target/src/api/include_api.cpp | 4 +- buildcc/lib/target/src/api/lib_api.cpp | 16 +- buildcc/lib/target/src/api/pch_api.cpp | 2 +- buildcc/lib/target/src/api/source_api.cpp | 3 +- buildcc/lib/target/src/api/sync_api.cpp | 181 +++++++----------- buildcc/lib/target/src/api/target_getter.cpp | 2 +- .../lib/target/src/api/target_info_getter.cpp | 34 ++-- .../lib/target/src/generator/generator.cpp | 21 +- .../target/src/generator/generator_loader.cpp | 57 ------ .../src/generator/generator_serialization.cpp | 71 +++++++ .../target/src/generator/generator_storer.cpp | 53 ----- buildcc/lib/target/src/generator/task.cpp | 20 +- buildcc/lib/target/src/target/build.cpp | 6 +- .../src/target/friend/compile_object.cpp | 75 ++++---- .../target/src/target/friend/compile_pch.cpp | 51 ++--- .../target/src/target/friend/link_target.cpp | 60 +++--- buildcc/lib/target/src/target/target.cpp | 4 +- .../lib/target/src/target/target_loader.cpp | 83 -------- .../src/target/target_serialization.cpp | 153 +++++++++++++++ .../lib/target/src/target/target_storer.cpp | 104 ---------- buildcc/lib/target/src/target/tasks.cpp | 21 +- buildcc/lib/target/test/target/CMakeLists.txt | 8 + .../test/target/test_builder_interface.cpp | 1 - .../target/test_serialization_interface.cpp | 115 +++++++++++ .../test/target/test_target_external_lib.cpp | 21 +- .../target/test_target_failure_states.cpp | 1 + .../target/test/target/test_target_flags.cpp | 44 +++-- .../test/target/test_target_include_dir.cpp | 71 +++---- .../test/target/test_target_lib_dep.cpp | 12 +- .../target/test/target/test_target_source.cpp | 27 +-- buildexe/src/toolchain_setup.cpp | 2 + 48 files changed, 994 insertions(+), 1055 deletions(-) delete mode 100644 buildcc/lib/target/include/target/base/generator_loader.h delete mode 100644 buildcc/lib/target/include/target/base/target_loader.h delete mode 100644 buildcc/lib/target/include/target/base/target_storer.h delete mode 100644 buildcc/lib/target/include/target/interface/loader_interface.h create mode 100644 buildcc/lib/target/include/target/interface/serialization_interface.h create mode 100644 buildcc/lib/target/include/target/serialization/generator_serialization.h create mode 100644 buildcc/lib/target/include/target/serialization/target_serialization.h delete mode 100644 buildcc/lib/target/src/generator/generator_loader.cpp create mode 100644 buildcc/lib/target/src/generator/generator_serialization.cpp delete mode 100644 buildcc/lib/target/src/generator/generator_storer.cpp delete mode 100644 buildcc/lib/target/src/target/target_loader.cpp create mode 100644 buildcc/lib/target/src/target/target_serialization.cpp delete mode 100644 buildcc/lib/target/src/target/target_storer.cpp create mode 100644 buildcc/lib/target/test/target/test_serialization_interface.cpp diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index 23fe6df6..fd538a3b 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -69,11 +69,11 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, target.AddIncludeDir("lib/target/include"); target.GlobHeaders("lib/target/include/target"); target.GlobHeaders("lib/target/include/target/api"); - target.GlobHeaders("lib/target/include/target/base"); target.GlobHeaders("lib/target/include/target/common"); target.GlobHeaders("lib/target/include/target/friend"); target.GlobHeaders("lib/target/include/target/interface"); target.GlobHeaders("lib/target/include/target/private"); + target.GlobHeaders("lib/target/include/target/serialization"); // ARGS target.GlobSources("lib/args/src"); diff --git a/buildcc/lib/target/cmake/common_target_src.cmake b/buildcc/lib/target/cmake/common_target_src.cmake index 5a662c46..88ec2a02 100644 --- a/buildcc/lib/target/cmake/common_target_src.cmake +++ b/buildcc/lib/target/cmake/common_target_src.cmake @@ -1,7 +1,7 @@ set(COMMON_TARGET_SRCS # Interfaces - include/target/interface/loader_interface.h include/target/interface/builder_interface.h + include/target/interface/serialization_interface.h # Common src/common/target_config.cpp @@ -40,9 +40,8 @@ set(COMMON_TARGET_SRCS include/target/api/target_getter.h # Base Generator - src/generator/generator_loader.cpp - src/generator/generator_storer.cpp - include/target/base/generator_loader.h + src/generator/generator_serialization.cpp + include/target/serialization/generator_serialization.h # Generator src/generator/generator.cpp @@ -57,10 +56,8 @@ set(COMMON_TARGET_SRCS include/target/friend/link_target.h # Base Target - src/target/target_loader.cpp - src/target/target_storer.cpp - include/target/base/target_loader.h - include/target/base/target_storer.h + src/target/target_serialization.cpp + include/target/serialization/target_serialization.h # Target src/target/target.cpp diff --git a/buildcc/lib/target/include/target/base/generator_loader.h b/buildcc/lib/target/include/target/base/generator_loader.h deleted file mode 100644 index a3bc0e85..00000000 --- a/buildcc/lib/target/include/target/base/generator_loader.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TARGET_BASE_GENERATOR_LOADER_H_ -#define TARGET_BASE_GENERATOR_LOADER_H_ - -#include "target/interface/loader_interface.h" - -#include -#include -#include - -#include "fmt/format.h" - -#include "target/common/path.h" - -namespace buildcc::internal { - -class GeneratorLoader : public LoaderInterface { -public: - GeneratorLoader(const std::string &name, const fs::path &absolute_path) - : name_(name), path_(absolute_path) { - binary_path_ = absolute_path / fmt::format("{}.bin", name); - } - - GeneratorLoader(const GeneratorLoader &loader) = delete; - - bool Load() override; - - // Getters - const internal::path_unordered_set &GetLoadedInputFiles() const noexcept { - return loaded_input_files_; - } - - const fs_unordered_set &GetLoadedOutputFiles() const noexcept { - return loaded_output_files_; - } - - const std::vector &GetLoadedCommands() const noexcept { - return loaded_commands_; - } - -private: - std::string name_; - fs::path path_; - - internal::path_unordered_set loaded_input_files_; - fs_unordered_set loaded_output_files_; - std::vector loaded_commands_; -}; - -} // namespace buildcc::internal - -#endif diff --git a/buildcc/lib/target/include/target/base/target_loader.h b/buildcc/lib/target/include/target/base/target_loader.h deleted file mode 100644 index 9bf1161f..00000000 --- a/buildcc/lib/target/include/target/base/target_loader.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TARGET_BASE_TARGET_LOADER_H_ -#define TARGET_BASE_TARGET_LOADER_H_ - -#include "target/interface/loader_interface.h" - -#include -#include - -#include "fmt/format.h" - -#include "target/common/path.h" - -namespace buildcc::internal { - -class TargetLoader : public LoaderInterface { -public: - explicit TargetLoader(const std::string &name, const fs::path &relative_path) - : name_(name), relative_path_(relative_path) { - binary_path_ = relative_path / fmt::format("{}.bin", name); - Initialize(); - } - - TargetLoader(const TargetLoader &loader) = delete; - -public: - bool Load() override; - - // Getters - const path_unordered_set &GetLoadedSources() const noexcept { - return loaded_sources_; - } - const path_unordered_set &GetLoadedHeaders() const noexcept { - return loaded_headers_; - } - const path_unordered_set &GetLoadedPchs() const noexcept { - return loaded_pchs_; - } - const path_unordered_set &GetLoadedLibDeps() const noexcept { - return loaded_lib_deps_; - } - const std::unordered_set & - GetLoadedExternalLibDeps() const noexcept { - return loaded_external_lib_dirs_; - } - - const fs_unordered_set &GetLoadedIncludeDirs() const noexcept { - return loaded_include_dirs_; - } - const fs_unordered_set &GetLoadedLibDirs() const noexcept { - return loaded_lib_dirs_; - } - const std::unordered_set & - GetLoadedPreprocessorFlags() const noexcept { - return loaded_preprocessor_flags_; - } - const std::unordered_set & - GetLoadedCommonCompileFlags() const noexcept { - return loaded_common_compile_flags_; - } - const std::unordered_set & - GetLoadedPchCompileFlags() const noexcept { - return loaded_pch_compile_flags_; - } - const std::unordered_set & - GetLoadedPchObjectFlags() const noexcept { - return loaded_pch_object_flags_; - } - const std::unordered_set & - GetLoadedAsmCompileFlags() const noexcept { - return loaded_asm_compile_flags_; - } - const std::unordered_set & - GetLoadedCCompileFlags() const noexcept { - return loaded_c_compile_flags_; - } - const std::unordered_set & - GetLoadedCppCompileFlags() const noexcept { - return loaded_cpp_compile_flags_; - } - const std::unordered_set &GetLoadedLinkFlags() const noexcept { - return loaded_link_flags_; - } - - const path_unordered_set &GetLoadedCompileDependencies() const noexcept { - return loaded_compile_dependencies_; - } - const path_unordered_set &GetLoadedLinkDependencies() const noexcept { - return loaded_link_dependencies_; - } - - bool GetLoadedPchCompiled() const noexcept { return loaded_pch_compiled_; } - bool GetLoadedTargetLinked() const noexcept { return loaded_target_linked_; } - -private: - void Initialize(); - -private: - std::string name_; - fs::path relative_path_; - - path_unordered_set loaded_sources_; - path_unordered_set loaded_headers_; - path_unordered_set loaded_pchs_; - path_unordered_set loaded_lib_deps_; - - std::unordered_set loaded_external_lib_dirs_; - - fs_unordered_set loaded_include_dirs_; - fs_unordered_set loaded_lib_dirs_; - - std::unordered_set loaded_preprocessor_flags_; - std::unordered_set loaded_common_compile_flags_; - std::unordered_set loaded_pch_compile_flags_; - std::unordered_set loaded_pch_object_flags_; - std::unordered_set loaded_asm_compile_flags_; - std::unordered_set loaded_c_compile_flags_; - std::unordered_set loaded_cpp_compile_flags_; - std::unordered_set loaded_link_flags_; - - path_unordered_set loaded_compile_dependencies_; - path_unordered_set loaded_link_dependencies_; - - bool loaded_pch_compiled_{false}; - bool loaded_target_linked_{false}; -}; - -} // namespace buildcc::internal - -#endif diff --git a/buildcc/lib/target/include/target/base/target_storer.h b/buildcc/lib/target/include/target/base/target_storer.h deleted file mode 100644 index c8cceea6..00000000 --- a/buildcc/lib/target/include/target/base/target_storer.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TARGET_BASE_TARGET_STORER_H_ -#define TARGET_BASE_TARGET_STORER_H_ - -#include - -#include "target/common/path.h" - -namespace buildcc::internal { - -struct TargetStorer { - internal::RelationalPathFiles current_source_files; - internal::RelationalPathFiles current_header_files; - internal::RelationalPathFiles current_pch_files; - - // NOTE, Order matters (BuildCC takes care of the order here) - std::vector current_user_lib_deps; - internal::path_unordered_set current_internal_lib_deps; - - fs_unordered_set current_include_dirs; - fs_unordered_set current_lib_dirs; - - // NOTE, Order matters (user takes care of the order here) - std::vector current_user_external_lib_deps; - std::unordered_set current_internal_external_lib_deps; - - std::unordered_set current_preprocessor_flags; - std::unordered_set current_common_compile_flags; - std::unordered_set current_pch_compile_flags; - std::unordered_set current_pch_object_flags; - std::unordered_set current_asm_compile_flags; - std::unordered_set current_c_compile_flags; - std::unordered_set current_cpp_compile_flags; - std::unordered_set current_link_flags; - - internal::RelationalPathFiles current_compile_dependencies; - internal::RelationalPathFiles current_link_dependencies; - - bool pch_compiled{false}; - bool target_linked{false}; -}; - -} // namespace buildcc::internal - -#endif diff --git a/buildcc/lib/target/include/target/common/path.h b/buildcc/lib/target/include/target/common/path.h index faa6e0f8..ad4314f1 100644 --- a/buildcc/lib/target/include/target/common/path.h +++ b/buildcc/lib/target/include/target/common/path.h @@ -18,6 +18,7 @@ #define TARGET_COMMON_PATH_H_ #include +#include #include // The Path class defined below is meant to be used with Sets @@ -142,49 +143,36 @@ class PathHash { typedef std::unordered_set path_unordered_set; typedef std::unordered_set fs_unordered_set; -// * Relation between -// - internal timestamp verified files (Path + Timestamp) -// - user facing file paths (Only Path) -// ? Why has this been done? -// We cannot guarantee that filepaths would be present -// when the user is defining the build -// The input to a Generator / Target might also be generated! -// We must only verify the File timestamp AFTER dependent Generator(s) / -// Target(s) have been built -// ? Why not do everything inside path_unordered_set? -// Users might want to query just the `fs_unordered_set` instead of the entire -// internal::path_unordered_set (The timestamp is internal information that the -// user does not need) -// In this case we opt for runtime (speed) optimization instead of memory -// optimization by caching the `user` information and `internal` information -// together -struct RelationalPathFiles { - RelationalPathFiles() {} - RelationalPathFiles(const path_unordered_set &i, const fs_unordered_set &u) - : internal(i), user(u) {} - - /** - * @brief Convert from fs_unordered_set to path_unordered_set - * Can assert throw if file does not exist when calling `CreateExistingPath` - */ - void Convert() { - if (done_once) { - return; - } - - done_once = true; - for (const auto &p : user) { - internal.emplace(Path::CreateExistingPath(p)); - } +inline std::vector +path_schema_convert(const std::vector &path_list, + const std::function &cb = + Path::CreateExistingPath) { + std::vector internal_path_list; + for (const auto &p : path_list) { + internal_path_list.push_back(cb(p)); } + return internal_path_list; +} -public: - path_unordered_set internal; - fs_unordered_set user; +inline path_unordered_set +path_schema_convert(const fs_unordered_set &path_set, + const std::function &cb = + Path::CreateExistingPath) { + path_unordered_set internal_path_set; + for (const auto &p : path_set) { + internal_path_set.insert(cb(p)); + } + return internal_path_set; +} -private: - bool done_once{false}; -}; +inline fs_unordered_set +path_schema_convert(const path_unordered_set &internal_path_set) { + fs_unordered_set path_set; + for (const auto &p : internal_path_set) { + path_set.insert(p.GetPathname()); + } + return path_set; +} } // namespace buildcc::internal diff --git a/buildcc/lib/target/include/target/generator.h b/buildcc/lib/target/include/target/generator.h index 0a9b463b..2e8b22f2 100644 --- a/buildcc/lib/target/include/target/generator.h +++ b/buildcc/lib/target/include/target/generator.h @@ -32,20 +32,25 @@ #include "target/interface/builder_interface.h" -#include "target/base/generator_loader.h" +#include "target/serialization/generator_serialization.h" #include "target/common/path.h" #include "target/common/target_env.h" namespace buildcc { +struct UserGeneratorSchema : public internal::GeneratorSchema { + fs_unordered_set inputs; +}; + class Generator : public internal::BuilderInterface { public: Generator(const std::string &name, const TargetEnv &env, bool parallel = false) : name_(name), generator_root_dir_(env.GetTargetRootDir()), generator_build_dir_(env.GetTargetBuildDir() / name), - loader_(name, generator_build_dir_), parallel_(parallel) { + serialization_(generator_build_dir_ / fmt::format("{}.bin", name)), + parallel_(parallel) { Initialize(); } virtual ~Generator() {} @@ -101,7 +106,9 @@ class Generator : public internal::BuilderInterface { void Build() override; // Getter - const fs::path &GetBinaryPath() const { return loader_.GetBinaryPath(); } + const fs::path &GetBinaryPath() const { + return serialization_.GetSerializedFile(); + } tf::Taskflow &GetTaskflow() { return tf_; } const std::string &GetName() const { return name_; } @@ -117,8 +124,6 @@ class Generator : public internal::BuilderInterface { void Convert(); void BuildGenerate(); - bool Store() override; - // Recheck states void InputRemoved(); void InputAdded(); @@ -132,13 +137,11 @@ class Generator : public internal::BuilderInterface { std::string name_; fs::path generator_root_dir_; fs::path generator_build_dir_; - internal::GeneratorLoader loader_; + internal::GeneratorSerialization serialization_; + bool parallel_{false}; // Serialization - internal::RelationalPathFiles current_input_files_; - fs_unordered_set current_output_files_; - std::vector current_commands_; - bool parallel_{false}; + UserGeneratorSchema user_; // Internal std::mutex task_state_mutex_; diff --git a/buildcc/lib/target/include/target/interface/builder_interface.h b/buildcc/lib/target/include/target/interface/builder_interface.h index d3ea59e9..cf2b7be8 100644 --- a/buildcc/lib/target/include/target/interface/builder_interface.h +++ b/buildcc/lib/target/include/target/interface/builder_interface.h @@ -106,9 +106,6 @@ class BuilderInterface { }); } -private: - virtual bool Store() = 0; - protected: bool dirty_{false}; std::string unique_id_; diff --git a/buildcc/lib/target/include/target/interface/loader_interface.h b/buildcc/lib/target/include/target/interface/loader_interface.h deleted file mode 100644 index 9bf838bd..00000000 --- a/buildcc/lib/target/include/target/interface/loader_interface.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TARGET_INTERFACE_LOADER_INTERFACE_H_ -#define TARGET_INTERFACE_LOADER_INTERFACE_H_ - -#include - -namespace fs = std::filesystem; - -namespace buildcc::internal { - -class LoaderInterface { -public: - virtual bool Load() = 0; - - const fs::path &GetBinaryPath() const { return binary_path_; }; - bool IsLoaded() const noexcept { return loaded_; }; - -protected: - bool loaded_{false}; - fs::path binary_path_; -}; - -} // namespace buildcc::internal - -#endif diff --git a/buildcc/lib/target/include/target/interface/serialization_interface.h b/buildcc/lib/target/include/target/interface/serialization_interface.h new file mode 100644 index 00000000..2e2ca654 --- /dev/null +++ b/buildcc/lib/target/include/target/interface/serialization_interface.h @@ -0,0 +1,76 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TARGET_INTERFACE_SERIALIZATION_INTERFACE_H_ +#define TARGET_INTERFACE_SERIALIZATION_INTERFACE_H_ + +#include + +#include "env/assert_fatal.h" +#include "env/util.h" + +#include "target/common/path.h" + +namespace fs = std::filesystem; + +namespace buildcc::internal { + +class SerializationInterface { +public: + SerializationInterface(const fs::path &serialized_file) + : serialized_file_(serialized_file) {} + virtual ~SerializationInterface() {} + + bool LoadFromFile() { + std::string buffer; + + // Read from serialized file + bool is_loaded = + env::load_file(path_as_string(serialized_file_).c_str(), true, &buffer); + if (!is_loaded) { + return false; + } + + // Verify serialized data as per schema + if (!Verify(buffer)) { + return false; + } + + // Load serialized data as C++ data + loaded_ = Load(buffer); + return loaded_; + } + + bool StoreToFile() { return Store(serialized_file_); } + + const fs::path &GetSerializedFile() const noexcept { + return serialized_file_; + } + bool IsLoaded() const noexcept { return loaded_; } + +private: + virtual bool Verify(const std::string &serialized_data) = 0; + virtual bool Load(const std::string &serialized_data) = 0; + virtual bool Store(const fs::path &absolute_serialized_file) = 0; + +private: + fs::path serialized_file_; + bool loaded_{false}; +}; + +} // namespace buildcc::internal + +#endif diff --git a/buildcc/lib/target/include/target/private/schema_util.h b/buildcc/lib/target/include/target/private/schema_util.h index d962e83e..b0ad689b 100644 --- a/buildcc/lib/target/include/target/private/schema_util.h +++ b/buildcc/lib/target/include/target/private/schema_util.h @@ -32,14 +32,28 @@ namespace buildcc::internal { inline void extract_path( const flatbuffers::Vector> *fbs_paths, - buildcc::internal::path_unordered_set &out) { + path_unordered_set &out) { if (fbs_paths == nullptr) { return; } for (auto iter = fbs_paths->begin(); iter != fbs_paths->end(); iter++) { - out.insert(buildcc::internal::Path::CreateNewPath( - iter->pathname()->c_str(), iter->last_write_timestamp())); + out.insert(Path::CreateNewPath(iter->pathname()->c_str(), + iter->last_write_timestamp())); + } +} + +inline void extract_path( + const flatbuffers::Vector> + *fbs_paths, + std::vector &out) { + if (fbs_paths == nullptr) { + return; + } + + for (auto iter = fbs_paths->begin(); iter != fbs_paths->end(); iter++) { + out.push_back(Path::CreateNewPath(iter->pathname()->c_str(), + iter->last_write_timestamp())); } } @@ -86,9 +100,10 @@ extract(const flatbuffers::Vector> // Create APIs for STORE +template inline std::vector> create_fbs_vector_path(flatbuffers::FlatBufferBuilder &builder, - const buildcc::internal::path_unordered_set &pathlist) { + const T &pathlist) { std::vector> paths; for (const auto &p : pathlist) { auto fbs_file = fbs::CreatePathDirect(builder, p.GetPathAsString().c_str(), diff --git a/buildcc/lib/target/include/target/serialization/generator_serialization.h b/buildcc/lib/target/include/target/serialization/generator_serialization.h new file mode 100644 index 00000000..dfe9553f --- /dev/null +++ b/buildcc/lib/target/include/target/serialization/generator_serialization.h @@ -0,0 +1,58 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TARGET_SERIALIZATION_GENERATOR_SERIALIZATION_H_ +#define TARGET_SERIALIZATION_GENERATOR_SERIALIZATION_H_ + +#include "target/interface/serialization_interface.h" + +#include +#include +#include + +#include "target/common/path.h" + +namespace buildcc::internal { + +struct GeneratorSchema { + std::string name; + path_unordered_set internal_inputs; + fs_unordered_set outputs; + std::vector commands; +}; + +class GeneratorSerialization : public SerializationInterface { +public: + GeneratorSerialization(const fs::path &serialized_file) + : SerializationInterface(serialized_file) {} + + void UpdateStore(const GeneratorSchema &store) { store_ = store; } + const GeneratorSchema &GetLoad() const { return load_; } + const GeneratorSchema &GetStore() const { return store_; } + +private: + bool Verify(const std::string &serialized_data) override; + bool Load(const std::string &serialized_data) override; + bool Store(const fs::path &absolute_serialized_file) override; + +private: + GeneratorSchema load_; + GeneratorSchema store_; +}; + +} // namespace buildcc::internal + +#endif diff --git a/buildcc/lib/target/include/target/serialization/target_serialization.h b/buildcc/lib/target/include/target/serialization/target_serialization.h new file mode 100644 index 00000000..c8e6b882 --- /dev/null +++ b/buildcc/lib/target/include/target/serialization/target_serialization.h @@ -0,0 +1,85 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TARGET_SERIALIZATION_TARGET_SERIALIZATION_H_ +#define TARGET_SERIALIZATION_TARGET_SERIALIZATION_H_ + +#include "target/interface/serialization_interface.h" + +#include + +#include "target/common/path.h" +#include "target/common/target_type.h" + +namespace buildcc::internal { + +struct TargetSchema { + std::string name; + TargetType type; + + path_unordered_set internal_sources; + path_unordered_set internal_headers; + path_unordered_set internal_pchs; + std::vector internal_libs; + std::vector external_libs; + + fs_unordered_set include_dirs; + fs_unordered_set lib_dirs; + + std::unordered_set preprocessor_flags; + std::unordered_set common_compile_flags; + std::unordered_set pch_compile_flags; + std::unordered_set pch_object_flags; + std::unordered_set asm_compile_flags; + std::unordered_set c_compile_flags; + std::unordered_set cpp_compile_flags; + std::unordered_set link_flags; + + path_unordered_set internal_compile_dependencies; + path_unordered_set internal_link_dependencies; + + bool pch_compiled{false}; + bool target_linked{false}; +}; + +class TargetSerialization : public SerializationInterface { +public: + TargetSerialization(const fs::path &serialized_file) + : SerializationInterface(serialized_file) {} + + void UpdatePchCompiled(const TargetSchema &store); + void UpdateTargetCompiled(); + void AddSource(const internal::Path &source); + void UpdateStore(const TargetSchema &store); + + const TargetSchema &GetLoad() const { return load_; } + const TargetSchema &GetStore() const { return store_; } + +private: + bool Verify(const std::string &serialized_data) override; + bool Load(const std::string &serialized_data) override; + bool Store(const fs::path &absolute_serialized_file) override; + +private: + TargetSchema load_; + TargetSchema store_; + + std::mutex add_source_mutex; +}; + +} // namespace buildcc::internal + +#endif diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index edcad7e7..f70ed25b 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -43,9 +43,8 @@ #include "target/friend/link_target.h" // Internal -#include "target/base/target_loader.h" -#include "target/base/target_storer.h" #include "target/common/path.h" +#include "target/serialization/target_serialization.h" // Env #include "env/env.h" @@ -75,8 +74,9 @@ class Target : public internal::BuilderInterface, env.GetTargetBuildDir() / toolchain.GetName() / name), config), name_(name), type_(type), toolchain_(toolchain), - loader_(name, env_.GetTargetBuildDir()), compile_pch_(*this), - compile_object_(*this), link_target_(*this) { + // loader_(name, env_.GetTargetBuildDir()), + serialization_(env_.GetTargetBuildDir() / fmt::format("{}.bin", name)), + compile_pch_(*this), compile_object_(*this), link_target_(*this) { Initialize(); } virtual ~Target() {} @@ -109,12 +109,9 @@ class Target : public internal::BuilderInterface, const fs_unordered_set ¤t_dirs); void RecheckFlags(const std::unordered_set &previous_flags, const std::unordered_set ¤t_flags); - void RecheckExternalLib( - const std::unordered_set &previous_external_libs, - const std::unordered_set ¤t_external_libs); - - // Fbs - bool Store() override; + void + RecheckExternalLib(const std::vector &previous_external_libs, + const std::vector ¤t_external_libs); // Tasks void SetTaskStateFailure(); @@ -143,7 +140,7 @@ class Target : public internal::BuilderInterface, std::string name_; TargetType type_; const Toolchain &toolchain_; - internal::TargetLoader loader_; + internal::TargetSerialization serialization_; // Friend classes internal::CompilePch compile_pch_; @@ -157,9 +154,6 @@ class Target : public internal::BuilderInterface, std::mutex task_state_mutex_; env::TaskState task_state_{env::TaskState::SUCCESS}; - std::mutex compiled_source_files_mutex_; - internal::path_unordered_set compiled_source_files_; - // env::Command command_; tf::Taskflow tf_; diff --git a/buildcc/lib/target/include/target/target_info.h b/buildcc/lib/target/include/target/target_info.h index 022df822..4250e85c 100644 --- a/buildcc/lib/target/include/target/target_info.h +++ b/buildcc/lib/target/include/target/target_info.h @@ -19,7 +19,6 @@ #include -#include "target/base/target_storer.h" #include "target/common/target_config.h" #include "target/common/target_env.h" #include "target/common/target_state.h" @@ -29,14 +28,25 @@ #include "target/api/include_api.h" #include "target/api/lib_api.h" #include "target/api/pch_api.h" -#include "target/api/sync_api.h" - #include "target/api/source_api.h" - +#include "target/api/sync_api.h" #include "target/api/target_info_getter.h" +#include "target/serialization/target_serialization.h" + namespace buildcc { +struct UserTargetSchema : public internal::TargetSchema { + fs_unordered_set sources; + fs_unordered_set headers; + fs_unordered_set pchs; + + std::vector libs; + + fs_unordered_set compile_dependencies; + fs_unordered_set link_dependencies; +}; + // NOTE: BaseTarget info is meant to hold information that is common to // multiple targets // It is also meant to be used in situations where we do not need to build @@ -72,7 +82,8 @@ class TargetInfo : public internal::SourceApi, TargetEnv env_; TargetConfig config_; - internal::TargetStorer storer_; + UserTargetSchema user_; + TargetState state_; }; diff --git a/buildcc/lib/target/src/api/deps_api.cpp b/buildcc/lib/target/src/api/deps_api.cpp index 63e59647..8cbee764 100644 --- a/buildcc/lib/target/src/api/deps_api.cpp +++ b/buildcc/lib/target/src/api/deps_api.cpp @@ -25,14 +25,14 @@ void DepsApi::AddCompileDependencyAbsolute(const fs::path &absolute_path) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_compile_dependencies.user.insert(absolute_path); + t.user_.compile_dependencies.insert(absolute_path); } template void DepsApi::AddLinkDependencyAbsolute(const fs::path &absolute_path) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_link_dependencies.user.insert(absolute_path); + t.user_.link_dependencies.insert(absolute_path); } template diff --git a/buildcc/lib/target/src/api/flag_api.cpp b/buildcc/lib/target/src/api/flag_api.cpp index abcfbcf7..99a9f294 100644 --- a/buildcc/lib/target/src/api/flag_api.cpp +++ b/buildcc/lib/target/src/api/flag_api.cpp @@ -25,55 +25,55 @@ void FlagApi::AddPreprocessorFlag(const std::string &flag) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_preprocessor_flags.insert(flag); + t.user_.preprocessor_flags.insert(flag); } template void FlagApi::AddCommonCompileFlag(const std::string &flag) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_common_compile_flags.insert(flag); + t.user_.common_compile_flags.insert(flag); } template void FlagApi::AddPchCompileFlag(const std::string &flag) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_pch_compile_flags.insert(flag); + t.user_.pch_compile_flags.insert(flag); } template void FlagApi::AddPchObjectFlag(const std::string &flag) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_pch_object_flags.insert(flag); + t.user_.pch_object_flags.insert(flag); } template void FlagApi::AddAsmCompileFlag(const std::string &flag) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_asm_compile_flags.insert(flag); + t.user_.asm_compile_flags.insert(flag); } template void FlagApi::AddCCompileFlag(const std::string &flag) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_c_compile_flags.insert(flag); + t.user_.c_compile_flags.insert(flag); } template void FlagApi::AddCppCompileFlag(const std::string &flag) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_cpp_compile_flags.insert(flag); + t.user_.cpp_compile_flags.insert(flag); } template void FlagApi::AddLinkFlag(const std::string &flag) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_link_flags.insert(flag); + t.user_.link_flags.insert(flag); } template class FlagApi; diff --git a/buildcc/lib/target/src/api/include_api.cpp b/buildcc/lib/target/src/api/include_api.cpp index bb9aa1b1..a1716935 100644 --- a/buildcc/lib/target/src/api/include_api.cpp +++ b/buildcc/lib/target/src/api/include_api.cpp @@ -26,7 +26,7 @@ void IncludeApi::AddHeaderAbsolute(const fs::path &absolute_filepath) { t.state_.ExpectsUnlock(); t.config_.ExpectsValidHeader(absolute_filepath); - t.storer_.current_header_files.user.insert(absolute_filepath); + t.user_.headers.insert(absolute_filepath); } template @@ -75,7 +75,7 @@ void IncludeApi::AddIncludeDirAbsolute(const fs::path &absolute_include_dir, T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_include_dirs.insert(absolute_include_dir); + t.user_.include_dirs.insert(absolute_include_dir); if (glob_headers) { GlobHeadersAbsolute(absolute_include_dir); diff --git a/buildcc/lib/target/src/api/lib_api.cpp b/buildcc/lib/target/src/api/lib_api.cpp index 0814927c..16eb85a8 100644 --- a/buildcc/lib/target/src/api/lib_api.cpp +++ b/buildcc/lib/target/src/api/lib_api.cpp @@ -22,33 +22,33 @@ namespace buildcc::internal { template -void LibApi::AddLibDir(const fs::path &relative_lib_dir) { +void LibApi::AddLibDirAbsolute(const fs::path &absolute_lib_dir) { T &t = static_cast(*this); - fs::path final_lib_dir = t.env_.GetTargetRootDir() / relative_lib_dir; - AddLibDirAbsolute(final_lib_dir); + t.state_.ExpectsUnlock(); + t.user_.lib_dirs.insert(absolute_lib_dir); } template -void LibApi::AddLibDirAbsolute(const fs::path &absolute_lib_dir) { +void LibApi::AddLibDir(const fs::path &relative_lib_dir) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); - t.storer_.current_lib_dirs.insert(absolute_lib_dir); + fs::path final_lib_dir = t.env_.GetTargetRootDir() / relative_lib_dir; + AddLibDirAbsolute(final_lib_dir); } template void LibApi::AddLibDep(const BaseTarget &lib_dep) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_user_lib_deps.push_back(lib_dep.GetTargetPath()); + t.user_.libs.push_back(lib_dep.GetTargetPath()); } template void LibApi::AddLibDep(const std::string &lib_dep) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.storer_.current_user_external_lib_deps.push_back(lib_dep); + t.user_.external_libs.push_back(lib_dep); } template class LibApi; diff --git a/buildcc/lib/target/src/api/pch_api.cpp b/buildcc/lib/target/src/api/pch_api.cpp index 885c5469..60d3745e 100644 --- a/buildcc/lib/target/src/api/pch_api.cpp +++ b/buildcc/lib/target/src/api/pch_api.cpp @@ -28,7 +28,7 @@ void PchApi::AddPchAbsolute(const fs::path &absolute_filepath) { t.config_.ExpectsValidHeader(absolute_filepath); const fs::path absolute_pch = fs::path(absolute_filepath).make_preferred(); - t.storer_.current_pch_files.user.insert(absolute_pch); + t.user_.pchs.insert(absolute_pch); } template diff --git a/buildcc/lib/target/src/api/source_api.cpp b/buildcc/lib/target/src/api/source_api.cpp index cce228df..78d260a9 100644 --- a/buildcc/lib/target/src/api/source_api.cpp +++ b/buildcc/lib/target/src/api/source_api.cpp @@ -26,8 +26,7 @@ void SourceApi::AddSourceAbsolute(const fs::path &absolute_source) { t.state_.ExpectsUnlock(); t.config_.ExpectsValidSource(absolute_source); - t.storer_.current_source_files.user.emplace( - fs::path(absolute_source).make_preferred()); + t.user_.sources.emplace(fs::path(absolute_source).make_preferred()); } template diff --git a/buildcc/lib/target/src/api/sync_api.cpp b/buildcc/lib/target/src/api/sync_api.cpp index d5efc349..261eca24 100644 --- a/buildcc/lib/target/src/api/sync_api.cpp +++ b/buildcc/lib/target/src/api/sync_api.cpp @@ -45,71 +45,57 @@ void SyncApi::SpecializedCopy(TargetType target, for (const SyncOption o : options) { switch (o) { case SyncOption::PreprocessorFlags: - t.storer_.current_preprocessor_flags = - std::move(target.storer_.current_preprocessor_flags); + t.user_.preprocessor_flags = std::move(target.user_.preprocessor_flags); break; case SyncOption::CommonCompileFlags: - t.storer_.current_common_compile_flags = - std::move(target.storer_.current_common_compile_flags); + t.user_.common_compile_flags = + std::move(target.user_.common_compile_flags); break; case SyncOption::PchCompileFlags: - t.storer_.current_pch_compile_flags = - std::move(target.storer_.current_pch_compile_flags); + t.user_.pch_compile_flags = std::move(target.user_.pch_compile_flags); break; case SyncOption::PchObjectFlags: - t.storer_.current_pch_object_flags = - std::move(target.storer_.current_pch_object_flags); + t.user_.pch_object_flags = std::move(target.user_.pch_object_flags); break; case SyncOption::AsmCompileFlags: - t.storer_.current_asm_compile_flags = - std::move(target.storer_.current_asm_compile_flags); + t.user_.asm_compile_flags = std::move(target.user_.asm_compile_flags); break; case SyncOption::CCompileFlags: - t.storer_.current_c_compile_flags = - std::move(target.storer_.current_c_compile_flags); + t.user_.c_compile_flags = std::move(target.user_.c_compile_flags); break; case SyncOption::CppCompileFlags: - t.storer_.current_cpp_compile_flags = - std::move(target.storer_.current_cpp_compile_flags); + t.user_.cpp_compile_flags = std::move(target.user_.cpp_compile_flags); break; case SyncOption::LinkFlags: - t.storer_.current_link_flags = - std::move(target.storer_.current_link_flags); + t.user_.link_flags = std::move(target.user_.link_flags); break; case SyncOption::CompileDependencies: - t.storer_.current_compile_dependencies.user = - std::move(target.storer_.current_compile_dependencies.user); + t.user_.compile_dependencies = + std::move(target.user_.compile_dependencies); break; case SyncOption::LinkDependencies: - t.storer_.current_link_dependencies.user = - std::move(target.storer_.current_link_dependencies.user); + t.user_.link_dependencies = std::move(target.user_.link_dependencies); break; case SyncOption::SourceFiles: - t.storer_.current_source_files.user = - std::move(target.storer_.current_source_files.user); + t.user_.sources = std::move(target.user_.sources); break; case SyncOption::HeaderFiles: - t.storer_.current_header_files.user = - std::move(target.storer_.current_header_files.user); + t.user_.headers = std::move(target.user_.headers); break; case SyncOption::PchFiles: - t.storer_.current_pch_files.user = - std::move(target.storer_.current_pch_files.user); + t.user_.pchs = std::move(target.user_.pchs); break; case SyncOption::LibDeps: - t.storer_.current_user_lib_deps = - std::move(target.storer_.current_user_lib_deps); + t.user_.libs = std::move(target.user_.libs); break; case SyncOption::IncludeDirs: - t.storer_.current_include_dirs = - std::move(target.storer_.current_include_dirs); + t.user_.include_dirs = std::move(target.user_.include_dirs); break; case SyncOption::LibDirs: - t.storer_.current_lib_dirs = std::move(target.storer_.current_lib_dirs); + t.user_.lib_dirs = std::move(target.user_.lib_dirs); break; case SyncOption::ExternalLibDeps: - t.storer_.current_user_external_lib_deps = - std::move(target.storer_.current_user_external_lib_deps); + t.user_.external_libs = std::move(target.user_.external_libs); break; default: env::assert_fatal("Invalid Option added"); @@ -140,116 +126,89 @@ void SyncApi::SpecializedInsert(TargetType target, for (const SyncOption o : options) { switch (o) { case SyncOption::PreprocessorFlags: - t.storer_.current_preprocessor_flags.insert( - std::make_move_iterator( - target.storer_.current_preprocessor_flags.begin()), - std::make_move_iterator( - target.storer_.current_preprocessor_flags.end())); + t.user_.preprocessor_flags.insert( + std::make_move_iterator(target.user_.preprocessor_flags.begin()), + std::make_move_iterator(target.user_.preprocessor_flags.end())); break; case SyncOption::CommonCompileFlags: - t.storer_.current_common_compile_flags.insert( - std::make_move_iterator( - target.storer_.current_common_compile_flags.begin()), - std::make_move_iterator( - target.storer_.current_common_compile_flags.end())); + t.user_.common_compile_flags.insert( + std::make_move_iterator(target.user_.common_compile_flags.begin()), + std::make_move_iterator(target.user_.common_compile_flags.end())); break; case SyncOption::PchCompileFlags: - t.storer_.current_pch_compile_flags.insert( - std::make_move_iterator( - target.storer_.current_pch_compile_flags.begin()), - std::make_move_iterator( - target.storer_.current_pch_compile_flags.end())); + t.user_.pch_compile_flags.insert( + std::make_move_iterator(target.user_.pch_compile_flags.begin()), + std::make_move_iterator(target.user_.pch_compile_flags.end())); break; case SyncOption::PchObjectFlags: - t.storer_.current_pch_object_flags.insert( - std::make_move_iterator( - target.storer_.current_pch_object_flags.begin()), - std::make_move_iterator( - target.storer_.current_pch_object_flags.end())); + t.user_.pch_object_flags.insert( + std::make_move_iterator(target.user_.pch_object_flags.begin()), + std::make_move_iterator(target.user_.pch_object_flags.end())); break; case SyncOption::AsmCompileFlags: - t.storer_.current_asm_compile_flags.insert( - std::make_move_iterator( - target.storer_.current_asm_compile_flags.begin()), - std::make_move_iterator( - target.storer_.current_asm_compile_flags.end())); + t.user_.asm_compile_flags.insert( + std::make_move_iterator(target.user_.asm_compile_flags.begin()), + std::make_move_iterator(target.user_.asm_compile_flags.end())); break; case SyncOption::CCompileFlags: - t.storer_.current_c_compile_flags.insert( - std::make_move_iterator( - target.storer_.current_c_compile_flags.begin()), - std::make_move_iterator( - target.storer_.current_c_compile_flags.end())); + t.user_.c_compile_flags.insert( + std::make_move_iterator(target.user_.c_compile_flags.begin()), + std::make_move_iterator(target.user_.c_compile_flags.end())); break; case SyncOption::CppCompileFlags: - t.storer_.current_cpp_compile_flags.insert( - std::make_move_iterator( - target.storer_.current_cpp_compile_flags.begin()), - std::make_move_iterator( - target.storer_.current_cpp_compile_flags.end())); + t.user_.cpp_compile_flags.insert( + std::make_move_iterator(target.user_.cpp_compile_flags.begin()), + std::make_move_iterator(target.user_.cpp_compile_flags.end())); break; case SyncOption::LinkFlags: - t.storer_.current_link_flags.insert( - std::make_move_iterator(target.storer_.current_link_flags.begin()), - std::make_move_iterator(target.storer_.current_link_flags.end())); + t.user_.link_flags.insert( + std::make_move_iterator(target.user_.link_flags.begin()), + std::make_move_iterator(target.user_.link_flags.end())); break; case SyncOption::CompileDependencies: - t.storer_.current_compile_dependencies.user.insert( - std::make_move_iterator( - target.storer_.current_compile_dependencies.user.begin()), - std::make_move_iterator( - target.storer_.current_compile_dependencies.user.end())); + t.user_.compile_dependencies.insert( + std::make_move_iterator(target.user_.compile_dependencies.begin()), + std::make_move_iterator(target.user_.compile_dependencies.end())); break; case SyncOption::LinkDependencies: - t.storer_.current_link_dependencies.user.insert( - std::make_move_iterator( - target.storer_.current_link_dependencies.user.begin()), - std::make_move_iterator( - target.storer_.current_link_dependencies.user.end())); + t.user_.link_dependencies.insert( + std::make_move_iterator(target.user_.link_dependencies.begin()), + std::make_move_iterator(target.user_.link_dependencies.end())); break; case SyncOption::SourceFiles: - t.storer_.current_source_files.user.insert( - std::make_move_iterator( - target.storer_.current_source_files.user.begin()), - std::make_move_iterator( - target.storer_.current_source_files.user.end())); + t.user_.sources.insert( + std::make_move_iterator(target.user_.sources.begin()), + std::make_move_iterator(target.user_.sources.end())); break; case SyncOption::HeaderFiles: - t.storer_.current_header_files.user.insert( - std::make_move_iterator( - target.storer_.current_header_files.user.begin()), - std::make_move_iterator( - target.storer_.current_header_files.user.end())); + t.user_.headers.insert( + std::make_move_iterator(target.user_.headers.begin()), + std::make_move_iterator(target.user_.headers.end())); break; case SyncOption::PchFiles: - t.storer_.current_pch_files.user.insert( - std::make_move_iterator( - target.storer_.current_pch_files.user.begin()), - std::make_move_iterator(target.storer_.current_pch_files.user.end())); + t.user_.pchs.insert(std::make_move_iterator(target.user_.pchs.begin()), + std::make_move_iterator(target.user_.pchs.end())); break; case SyncOption::LibDeps: - t.storer_.current_user_lib_deps.insert( - t.storer_.current_user_lib_deps.end(), - std::make_move_iterator(target.storer_.current_user_lib_deps.begin()), - std::make_move_iterator(target.storer_.current_user_lib_deps.end())); + t.user_.libs.insert(t.user_.libs.end(), + std::make_move_iterator(target.user_.libs.begin()), + std::make_move_iterator(target.user_.libs.end())); break; case SyncOption::IncludeDirs: - t.storer_.current_include_dirs.insert( - std::make_move_iterator(target.storer_.current_include_dirs.begin()), - std::make_move_iterator(target.storer_.current_include_dirs.end())); + t.user_.include_dirs.insert( + std::make_move_iterator(target.user_.include_dirs.begin()), + std::make_move_iterator(target.user_.include_dirs.end())); break; case SyncOption::LibDirs: - t.storer_.current_lib_dirs.insert( - std::make_move_iterator(target.storer_.current_lib_dirs.begin()), - std::make_move_iterator(target.storer_.current_lib_dirs.end())); + t.user_.lib_dirs.insert( + std::make_move_iterator(target.user_.lib_dirs.begin()), + std::make_move_iterator(target.user_.lib_dirs.end())); break; case SyncOption::ExternalLibDeps: - t.storer_.current_user_external_lib_deps.insert( - t.storer_.current_user_external_lib_deps.end(), - std::make_move_iterator( - target.storer_.current_user_external_lib_deps.begin()), - std::make_move_iterator( - target.storer_.current_user_external_lib_deps.end())); + t.user_.external_libs.insert( + t.user_.external_libs.end(), + std::make_move_iterator(target.user_.external_libs.begin()), + std::make_move_iterator(target.user_.external_libs.end())); break; default: env::assert_fatal("Invalid Option added"); diff --git a/buildcc/lib/target/src/api/target_getter.cpp b/buildcc/lib/target/src/api/target_getter.cpp index 83cad46e..e49e30ef 100644 --- a/buildcc/lib/target/src/api/target_getter.cpp +++ b/buildcc/lib/target/src/api/target_getter.cpp @@ -23,7 +23,7 @@ namespace buildcc::internal { template const fs::path &TargetGetter::GetBinaryPath() const { const T &t = static_cast(*this); - return t.loader_.GetBinaryPath(); + return t.serialization_.GetSerializedFile(); } template const fs::path &TargetGetter::GetTargetPath() const { diff --git a/buildcc/lib/target/src/api/target_info_getter.cpp b/buildcc/lib/target/src/api/target_info_getter.cpp index 10b18a2f..488818a7 100644 --- a/buildcc/lib/target/src/api/target_info_getter.cpp +++ b/buildcc/lib/target/src/api/target_info_getter.cpp @@ -67,28 +67,28 @@ template const fs_unordered_set &TargetInfoGetter::GetSourceFiles() const { const T &t = static_cast(*this); - return t.storer_.current_source_files.user; + return t.user_.sources; } template const fs_unordered_set &TargetInfoGetter::GetHeaderFiles() const { const T &t = static_cast(*this); - return t.storer_.current_header_files.user; + return t.user_.headers; } template const fs_unordered_set &TargetInfoGetter::GetPchFiles() const { const T &t = static_cast(*this); - return t.storer_.current_pch_files.user; + return t.user_.pchs; } template const std::vector &TargetInfoGetter::GetLibDeps() const { const T &t = static_cast(*this); - return t.storer_.current_user_lib_deps; + return t.user_.libs; } template @@ -96,21 +96,21 @@ const std::vector & TargetInfoGetter::GetExternalLibDeps() const { const T &t = static_cast(*this); - return t.storer_.current_user_external_lib_deps; + return t.user_.external_libs; } template const fs_unordered_set &TargetInfoGetter::GetIncludeDirs() const { const T &t = static_cast(*this); - return t.storer_.current_include_dirs; + return t.user_.include_dirs; } template const fs_unordered_set &TargetInfoGetter::GetLibDirs() const { const T &t = static_cast(*this); - return t.storer_.current_lib_dirs; + return t.user_.lib_dirs; } template @@ -118,7 +118,7 @@ const std::unordered_set & TargetInfoGetter::GetPreprocessorFlags() const { const T &t = static_cast(*this); - return t.storer_.current_preprocessor_flags; + return t.user_.preprocessor_flags; } template @@ -126,7 +126,7 @@ const std::unordered_set & TargetInfoGetter::GetCommonCompileFlags() const { const T &t = static_cast(*this); - return t.storer_.current_common_compile_flags; + return t.user_.common_compile_flags; } template @@ -134,7 +134,7 @@ const std::unordered_set & TargetInfoGetter::GetPchCompileFlags() const { const T &t = static_cast(*this); - return t.storer_.current_pch_compile_flags; + return t.user_.pch_compile_flags; } template @@ -142,7 +142,7 @@ const std::unordered_set & TargetInfoGetter::GetPchObjectFlags() const { const T &t = static_cast(*this); - return t.storer_.current_pch_object_flags; + return t.user_.pch_object_flags; } template @@ -150,7 +150,7 @@ const std::unordered_set & TargetInfoGetter::GetAsmCompileFlags() const { const T &t = static_cast(*this); - return t.storer_.current_asm_compile_flags; + return t.user_.asm_compile_flags; } template @@ -158,7 +158,7 @@ const std::unordered_set & TargetInfoGetter::GetCCompileFlags() const { const T &t = static_cast(*this); - return t.storer_.current_c_compile_flags; + return t.user_.c_compile_flags; } template @@ -166,7 +166,7 @@ const std::unordered_set & TargetInfoGetter::GetCppCompileFlags() const { const T &t = static_cast(*this); - return t.storer_.current_cpp_compile_flags; + return t.user_.cpp_compile_flags; } template @@ -174,21 +174,21 @@ const std::unordered_set & TargetInfoGetter::GetLinkFlags() const { const T &t = static_cast(*this); - return t.storer_.current_link_flags; + return t.user_.link_flags; } template const fs_unordered_set &TargetInfoGetter::GetCompileDependencies() const { const T &t = static_cast(*this); - return t.storer_.current_compile_dependencies.user; + return t.user_.compile_dependencies; } template const fs_unordered_set &TargetInfoGetter::GetLinkDependencies() const { const T &t = static_cast(*this); - return t.storer_.current_link_dependencies.user; + return t.user_.link_dependencies; } template class TargetInfoGetter; diff --git a/buildcc/lib/target/src/generator/generator.cpp b/buildcc/lib/target/src/generator/generator.cpp index caa2ada9..bd935db3 100644 --- a/buildcc/lib/target/src/generator/generator.cpp +++ b/buildcc/lib/target/src/generator/generator.cpp @@ -33,7 +33,7 @@ void Generator::AddInput(const std::string &absolute_input_pattern, command_.Construct(absolute_input_pattern); const auto absolute_input_path = internal::Path::CreateNewPath(absolute_input_string); - current_input_files_.user.insert(absolute_input_path.GetPathname()); + user_.inputs.insert(absolute_input_path.GetPathname()); if (identifier != nullptr) { command_.AddDefaultArgument(identifier, @@ -47,7 +47,7 @@ void Generator::AddOutput(const std::string &absolute_output_pattern, command_.Construct(absolute_output_pattern); const auto absolute_output_path = internal::Path::CreateNewPath(absolute_output_string); - current_output_files_.insert(absolute_output_path.GetPathname()); + user_.outputs.insert(absolute_output_path.GetPathname()); if (identifier != nullptr) { command_.AddDefaultArgument(identifier, @@ -60,11 +60,11 @@ void Generator::AddCommand( const std::unordered_map &arguments) { std::string constructed_command = command_.Construct(command_pattern, arguments); - current_commands_.emplace_back(std::move(constructed_command)); + user_.commands.emplace_back(std::move(constructed_command)); } void Generator::Build() { - (void)loader_.Load(); + (void)serialization_.LoadFromFile(); GenerateTask(); } @@ -94,19 +94,22 @@ void Generator::Initialize() { tf_.name(name_); } -void Generator::Convert() { current_input_files_.Convert(); } +void Generator::Convert() { + user_.internal_inputs = internal::path_schema_convert( + user_.inputs, internal::Path::CreateExistingPath); +} void Generator::BuildGenerate() { - if (!loader_.IsLoaded()) { + if (!serialization_.IsLoaded()) { dirty_ = true; } else { RecheckPaths( - loader_.GetLoadedInputFiles(), current_input_files_.internal, + serialization_.GetLoad().internal_inputs, user_.internal_inputs, [&]() { InputRemoved(); }, [&]() { InputAdded(); }, [&]() { InputUpdated(); }); - RecheckChanged(loader_.GetLoadedOutputFiles(), current_output_files_, + RecheckChanged(serialization_.GetLoad().outputs, user_.outputs, [&]() { OutputChanged(); }); - RecheckChanged(loader_.GetLoadedCommands(), current_commands_, + RecheckChanged(serialization_.GetLoad().commands, user_.commands, [&]() { CommandChanged(); }); } } diff --git a/buildcc/lib/target/src/generator/generator_loader.cpp b/buildcc/lib/target/src/generator/generator_loader.cpp deleted file mode 100644 index 0a54b820..00000000 --- a/buildcc/lib/target/src/generator/generator_loader.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/base/generator_loader.h" - -#include "env/logging.h" -#include "env/util.h" - -// Private -#include "target/private/schema_util.h" - -#include "generator_generated.h" - -namespace buildcc::internal { - -bool GeneratorLoader::Load() { - env::log_trace(name_, __FUNCTION__); - - auto file_path = GetBinaryPath(); - std::string buffer; - bool is_loaded = - env::load_file(path_as_string(file_path).c_str(), true, &buffer); - if (!is_loaded) { - return false; - } - - flatbuffers::Verifier verifier((const uint8_t *)buffer.c_str(), - buffer.length()); - const bool is_verified = fbs::VerifyGeneratorBuffer(verifier); - if (!is_verified) { - return false; - } - - const auto *generator = fbs::GetGenerator((const void *)buffer.c_str()); - - extract_path(generator->inputs(), loaded_input_files_); - extract(generator->outputs(), loaded_output_files_); - extract(generator->commands(), loaded_commands_); - - loaded_ = true; - return true; -} - -} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/generator/generator_serialization.cpp b/buildcc/lib/target/src/generator/generator_serialization.cpp new file mode 100644 index 00000000..855aae04 --- /dev/null +++ b/buildcc/lib/target/src/generator/generator_serialization.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "target/serialization/generator_serialization.h" + +// Third party +#include "flatbuffers/flatbuffers.h" + +// Private +#include "target/private/schema_util.h" + +// Schema generated +#include "generator_generated.h" + +namespace buildcc::internal { + +// PRIVATE + +bool GeneratorSerialization::Verify(const std::string &serialized_data) { + flatbuffers::Verifier verifier((const uint8_t *)serialized_data.c_str(), + serialized_data.length()); + return fbs::VerifyGeneratorBuffer(verifier); +} + +bool GeneratorSerialization::Load(const std::string &serialized_data) { + const auto *generator = + fbs::GetGenerator((const void *)serialized_data.c_str()); + if (generator == nullptr) { + return false; + } + + extract_path(generator->inputs(), load_.internal_inputs); + extract(generator->outputs(), load_.outputs); + extract(generator->commands(), load_.commands); + return true; +} + +bool GeneratorSerialization::Store(const fs::path &absolute_serialized_file) { + flatbuffers::FlatBufferBuilder builder; + + auto fbs_input_files = + internal::create_fbs_vector_path(builder, store_.internal_inputs); + auto fbs_output_files = + internal::create_fbs_vector_string(builder, store_.outputs); + auto fbs_commands = + internal::create_fbs_vector_string(builder, store_.commands); + + auto fbs_generator = + fbs::CreateGeneratorDirect(builder, store_.name.c_str(), &fbs_input_files, + &fbs_output_files, &fbs_commands); + fbs::FinishGeneratorBuffer(builder, fbs_generator); + + return env::save_file(path_as_string(absolute_serialized_file).c_str(), + (const char *)builder.GetBufferPointer(), + builder.GetSize(), true); +} + +} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/generator/generator_storer.cpp b/buildcc/lib/target/src/generator/generator_storer.cpp deleted file mode 100644 index a652e5ff..00000000 --- a/buildcc/lib/target/src/generator/generator_storer.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/generator.h" - -#include "flatbuffers/flatbuffers.h" - -#include "env/util.h" - -#include "generator_generated.h" -#include "target/private/schema_util.h" - -namespace fbs = schema::internal; - -namespace buildcc { - -bool Generator::Store() { - env::log_trace(name_, __FUNCTION__); - - flatbuffers::FlatBufferBuilder builder; - - auto fbs_input_files = - internal::create_fbs_vector_path(builder, current_input_files_.internal); - auto fbs_output_files = - internal::create_fbs_vector_string(builder, current_output_files_); - auto fbs_commands = - internal::create_fbs_vector_string(builder, current_commands_); - - auto fbs_generator = - fbs::CreateGeneratorDirect(builder, name_.c_str(), &fbs_input_files, - &fbs_output_files, &fbs_commands); - fbs::FinishGeneratorBuffer(builder, fbs_generator); - - const fs::path file_path = GetBinaryPath(); - return env::save_file(path_as_string(file_path).c_str(), - (const char *)builder.GetBufferPointer(), - builder.GetSize(), true); -} - -} // namespace buildcc diff --git a/buildcc/lib/target/src/generator/task.cpp b/buildcc/lib/target/src/generator/task.cpp index 8ee2fb8c..c4118114 100644 --- a/buildcc/lib/target/src/generator/task.cpp +++ b/buildcc/lib/target/src/generator/task.cpp @@ -62,11 +62,11 @@ void Generator::GenerateTask() { tf::Task command_task; if (dirty_) { if (parallel_) { - command_task = subflow.for_each(current_commands_.cbegin(), - current_commands_.cend(), run_command); + command_task = subflow.for_each(user_.commands.cbegin(), + user_.commands.cend(), run_command); } else { command_task = subflow.emplace([&, run_command]() { - for (const auto &command : current_commands_) { + for (const auto &command : user_.commands) { run_command(command); } }); @@ -77,14 +77,14 @@ void Generator::GenerateTask() { command_task.name(kCommandTaskName); // Graph Generation - for (const auto &i : current_input_files_.user) { + for (const auto &i : user_.inputs) { std::string name = fmt::format("{}", i.lexically_relative(env::get_project_root_dir())); tf::Task task = subflow.placeholder().name(name); task.precede(command_task); } - for (const auto &o : current_output_files_) { + for (const auto &o : user_.outputs) { std::string name = fmt::format("{}", o.lexically_relative(env::get_project_root_dir())); tf::Task task = subflow.placeholder().name(name); @@ -103,15 +103,15 @@ void Generator::GenerateTask() { if (task_state_ == env::TaskState::SUCCESS) { if (dirty_) { try { - env::assert_throw(Store(), fmt::format("Store failed for {}", name_)); + serialization_.UpdateStore(user_); + env::assert_throw(serialization_.StoreToFile(), + fmt::format("Store failed for {}", name_)); } catch (...) { task_state_ = env::TaskState::FAILURE; } } - } - - // Update Env task state when NOT SUCCESS only - if (task_state_ != env::TaskState::SUCCESS) { + } else { + // not SUCCESS state env::set_task_state(task_state_); } }); diff --git a/buildcc/lib/target/src/target/build.cpp b/buildcc/lib/target/src/target/build.cpp index 82e00a53..4e9de6c6 100644 --- a/buildcc/lib/target/src/target/build.cpp +++ b/buildcc/lib/target/src/target/build.cpp @@ -58,13 +58,13 @@ void Target::Build() { state_.SetLock(); // PCH state - if (!storer_.current_pch_files.user.empty()) { + if (!user_.pchs.empty()) { state_.SetPch(); } // Source - Object relation // Source state - for (const auto &abs_source : storer_.current_source_files.user) { + for (const auto &abs_source : user_.sources) { // Set state state_.SetSourceState(config_.GetFileExt(abs_source)); @@ -94,7 +94,7 @@ void Target::Build() { }); // Load the serialized file - (void)loader_.Load(); + (void)serialization_.LoadFromFile(); // Target State Tasks StartTask(); diff --git a/buildcc/lib/target/src/target/friend/compile_object.cpp b/buildcc/lib/target/src/target/friend/compile_object.cpp index a2c418f7..846108df 100644 --- a/buildcc/lib/target/src/target/friend/compile_object.cpp +++ b/buildcc/lib/target/src/target/friend/compile_object.cpp @@ -165,30 +165,31 @@ void CompileObject::BuildObjectCompile( std::vector &dummy_source_files) { PreObjectCompile(); - const auto &loader = target_.loader_; - const auto &storer = target_.storer_; + const auto &serialization = target_.serialization_; + const auto &load_target_schema = serialization.GetLoad(); + const auto &user_target_schema = target_.user_; - if (!loader.IsLoaded()) { + if (!serialization.IsLoaded()) { target_.dirty_ = true; } else { - target_.RecheckFlags(loader.GetLoadedPreprocessorFlags(), - target_.GetPreprocessorFlags()); - target_.RecheckFlags(loader.GetLoadedCommonCompileFlags(), - target_.GetCommonCompileFlags()); - target_.RecheckFlags(loader.GetLoadedPchObjectFlags(), - target_.GetPchObjectFlags()); - target_.RecheckFlags(loader.GetLoadedAsmCompileFlags(), - target_.GetAsmCompileFlags()); - target_.RecheckFlags(loader.GetLoadedCCompileFlags(), - target_.GetCCompileFlags()); - target_.RecheckFlags(loader.GetLoadedCppCompileFlags(), - target_.GetCppCompileFlags()); - target_.RecheckDirs(loader.GetLoadedIncludeDirs(), - target_.GetIncludeDirs()); - target_.RecheckPaths(loader.GetLoadedHeaders(), - storer.current_header_files.internal); - target_.RecheckPaths(loader.GetLoadedCompileDependencies(), - storer.current_compile_dependencies.internal); + target_.RecheckFlags(load_target_schema.preprocessor_flags, + user_target_schema.preprocessor_flags); + target_.RecheckFlags(load_target_schema.common_compile_flags, + user_target_schema.common_compile_flags); + target_.RecheckFlags(load_target_schema.pch_object_flags, + user_target_schema.pch_object_flags); + target_.RecheckFlags(load_target_schema.asm_compile_flags, + user_target_schema.asm_compile_flags); + target_.RecheckFlags(load_target_schema.c_compile_flags, + user_target_schema.c_compile_flags); + target_.RecheckFlags(load_target_schema.cpp_compile_flags, + user_target_schema.cpp_compile_flags); + target_.RecheckDirs(load_target_schema.include_dirs, + user_target_schema.include_dirs); + target_.RecheckPaths(load_target_schema.internal_headers, + user_target_schema.internal_headers); + target_.RecheckPaths(load_target_schema.internal_compile_dependencies, + user_target_schema.internal_compile_dependencies); } if (target_.dirty_) { @@ -199,39 +200,41 @@ void CompileObject::BuildObjectCompile( } void CompileObject::PreObjectCompile() { - auto &storer = target_.storer_; + auto &target_user_schema = target_.user_; // Convert user_source_files to current_source_files - storer.current_source_files.Convert(); + target_user_schema.internal_sources = + internal::path_schema_convert(target_user_schema.sources); // Convert user_header_files to current_header_files - storer.current_header_files.Convert(); + target_user_schema.internal_headers = + internal::path_schema_convert(target_user_schema.headers); // Convert user_compile_dependencies to current_compile_dependencies - storer.current_compile_dependencies.Convert(); + target_user_schema.internal_compile_dependencies = + internal::path_schema_convert(target_user_schema.compile_dependencies); } void CompileObject::CompileSources(std::vector &source_files) { - const auto &storer = target_.storer_; + const auto &target_user_schema = target_.user_; source_files = - std::vector(storer.current_source_files.internal.begin(), - storer.current_source_files.internal.end()); + std::vector(target_user_schema.internal_sources.begin(), + target_user_schema.internal_sources.end()); } void CompileObject::RecompileSources( std::vector &source_files, std::vector &dummy_source_files) { - const auto &loader = target_.loader_; - const auto &storer = target_.storer_; - - const auto &previous_source_files = loader.GetLoadedSources(); + const auto &serialization = target_.serialization_; + const auto &user_target_schema = target_.user_; + const auto &previous_source_files = serialization.GetLoad().internal_sources; // * Cannot find previous source in current source files const bool is_source_removed = std::any_of(previous_source_files.begin(), previous_source_files.end(), [&](const internal::Path &p) { - return storer.current_source_files.internal.find(p) == - storer.current_source_files.internal.end(); + return user_target_schema.internal_sources.find(p) == + user_target_schema.internal_sources.end(); }); if (is_source_removed) { @@ -239,9 +242,7 @@ void CompileObject::RecompileSources( target_.SourceRemoved(); } - for (const auto ¤t_file : storer.current_source_files.internal) { - // const auto ¤t_source = current_file.GetPathname(); - + for (const auto ¤t_file : user_target_schema.internal_sources) { // Find current_file in the loaded sources auto iter = previous_source_files.find(current_file); diff --git a/buildcc/lib/target/src/target/friend/compile_pch.cpp b/buildcc/lib/target/src/target/friend/compile_pch.cpp index 2d4057ba..115138ab 100644 --- a/buildcc/lib/target/src/target/friend/compile_pch.cpp +++ b/buildcc/lib/target/src/target/friend/compile_pch.cpp @@ -73,29 +73,31 @@ void CompilePch::CacheCompileCommand() { void CompilePch::BuildCompile() { PreCompile(); - const auto &loader = target_.loader_; + const auto &serialization = target_.serialization_; + const auto &load_target_schema = serialization.GetLoad(); + const auto &user_target_schema = target_.user_; - if (!loader.IsLoaded()) { + if (!serialization.IsLoaded()) { target_.dirty_ = true; } else { - target_.RecheckFlags(loader.GetLoadedPreprocessorFlags(), - target_.GetPreprocessorFlags()); - target_.RecheckFlags(loader.GetLoadedCommonCompileFlags(), - target_.GetCommonCompileFlags()); - target_.RecheckFlags(loader.GetLoadedCCompileFlags(), - target_.GetCCompileFlags()); - target_.RecheckFlags(loader.GetLoadedCppCompileFlags(), - target_.GetCppCompileFlags()); - target_.RecheckDirs(loader.GetLoadedIncludeDirs(), - target_.GetIncludeDirs()); - target_.RecheckPaths(loader.GetLoadedHeaders(), - target_.storer_.current_header_files.internal); - - target_.RecheckFlags(loader.GetLoadedPchCompileFlags(), - target_.GetPchCompileFlags()); - target_.RecheckPaths(loader.GetLoadedPchs(), - target_.storer_.current_pch_files.internal); - if (!loader.GetLoadedPchCompiled()) { + target_.RecheckFlags(load_target_schema.preprocessor_flags, + user_target_schema.preprocessor_flags); + target_.RecheckFlags(load_target_schema.common_compile_flags, + user_target_schema.common_compile_flags); + target_.RecheckFlags(load_target_schema.c_compile_flags, + user_target_schema.c_compile_flags); + target_.RecheckFlags(load_target_schema.cpp_compile_flags, + user_target_schema.cpp_compile_flags); + target_.RecheckDirs(load_target_schema.include_dirs, + user_target_schema.include_dirs); + target_.RecheckPaths(load_target_schema.internal_headers, + user_target_schema.internal_headers); + + target_.RecheckFlags(load_target_schema.pch_compile_flags, + user_target_schema.pch_compile_flags); + target_.RecheckPaths(load_target_schema.internal_pchs, + user_target_schema.internal_pchs); + if (!load_target_schema.pch_compiled) { target_.dirty_ = true; } } @@ -110,7 +112,6 @@ void CompilePch::BuildCompile() { } bool success = env::Command::Execute(command_); env::assert_throw(success, "Failed to compile pch"); - target_.storer_.pch_compiled = true; } } @@ -158,9 +159,13 @@ std::string CompilePch::ConstructCompileCommand() const { } void CompilePch::PreCompile() { - target_.storer_.current_header_files.Convert(); + auto &target_user_schema = target_.user_; - target_.storer_.current_pch_files.Convert(); + target_user_schema.internal_headers = + internal::path_schema_convert(target_user_schema.headers); + + target_user_schema.internal_pchs = + internal::path_schema_convert(target_user_schema.pchs); } } // namespace buildcc::internal diff --git a/buildcc/lib/target/src/target/friend/link_target.cpp b/buildcc/lib/target/src/target/friend/link_target.cpp index 42b4208d..2c6fd30e 100644 --- a/buildcc/lib/target/src/target/friend/link_target.cpp +++ b/buildcc/lib/target/src/target/friend/link_target.cpp @@ -34,18 +34,15 @@ void LinkTarget::CacheLinkCommand() { internal::aggregate(target_.compile_object_.GetCompiledSources()); const std::string output_target = fmt::format("{}", output_); - - const auto &storer = target_.storer_; + const auto &target_user_schema = target_.user_; command_ = target_.command_.Construct( target_.config_.link_command, { {kOutput, output_target}, {kCompiledSources, aggregated_compiled_sources}, - // NOTE, This needs to be ORDERED {kLibDeps, - fmt::format( - "{} {}", internal::aggregate(storer.current_user_lib_deps), - internal::aggregate(storer.current_user_external_lib_deps))}, + fmt::format("{} {}", internal::aggregate(target_user_schema.libs), + internal::aggregate(target_user_schema.external_libs))}, }); } @@ -60,40 +57,41 @@ fs::path LinkTarget::ConstructOutputPath() const { } void LinkTarget::PreLink() { - auto &storer = target_.storer_; - - for (const auto &p : storer.current_user_lib_deps) { - storer.current_internal_lib_deps.emplace( - internal::Path::CreateExistingPath(p)); - } + auto &target_user_schema = target_.user_; - storer.current_internal_external_lib_deps.insert( - storer.current_user_external_lib_deps.begin(), - storer.current_user_external_lib_deps.end()); + target_user_schema.internal_libs = + path_schema_convert(target_user_schema.libs); - storer.current_link_dependencies.Convert(); + target_user_schema.internal_link_dependencies = + path_schema_convert(target_user_schema.link_dependencies); } void LinkTarget::BuildLink() { PreLink(); - const auto &loader = target_.loader_; - const auto &storer = target_.storer_; + const auto &serialization = target_.serialization_; + const auto &target_load_schema = serialization.GetLoad(); + const auto &target_user_schema = target_.user_; - if (!loader.IsLoaded()) { + if (!serialization.IsLoaded()) { target_.dirty_ = true; } else { - target_.RecheckFlags(loader.GetLoadedLinkFlags(), target_.GetLinkFlags()); - target_.RecheckDirs(loader.GetLoadedLibDirs(), target_.GetLibDirs()); - target_.RecheckExternalLib(loader.GetLoadedExternalLibDeps(), - storer.current_internal_external_lib_deps); - target_.RecheckPaths(loader.GetLoadedLinkDependencies(), - storer.current_link_dependencies.internal); - - // NOTE, This needs to be UNORDERED - target_.RecheckPaths(loader.GetLoadedLibDeps(), - storer.current_internal_lib_deps); - if (!loader.GetLoadedTargetLinked()) { + target_.RecheckFlags(target_load_schema.link_flags, + target_user_schema.link_flags); + target_.RecheckDirs(target_load_schema.lib_dirs, + target_user_schema.lib_dirs); + target_.RecheckExternalLib(target_load_schema.external_libs, + target_user_schema.external_libs); + target_.RecheckPaths(target_load_schema.internal_link_dependencies, + target_user_schema.internal_link_dependencies); + path_unordered_set target_loaded_libs( + target_load_schema.internal_libs.begin(), + target_load_schema.internal_libs.end()); + path_unordered_set target_user_libs( + target_user_schema.internal_libs.begin(), + target_user_schema.internal_libs.end()); + target_.RecheckPaths(target_loaded_libs, target_user_libs); + if (!target_load_schema.target_linked) { target_.dirty_ = true; } } @@ -101,7 +99,7 @@ void LinkTarget::BuildLink() { if (target_.dirty_) { bool success = env::Command::Execute(command_); env::assert_throw(success, "Failed to link target"); - target_.storer_.target_linked = true; + target_.serialization_.UpdateTargetCompiled(); } } diff --git a/buildcc/lib/target/src/target/target.cpp b/buildcc/lib/target/src/target/target.cpp index fe069f31..571cd9a4 100644 --- a/buildcc/lib/target/src/target/target.cpp +++ b/buildcc/lib/target/src/target/target.cpp @@ -83,8 +83,8 @@ void Target::RecheckFlags( } void Target::RecheckExternalLib( - const std::unordered_set &previous_external_libs, - const std::unordered_set ¤t_external_libs) { + const std::vector &previous_external_libs, + const std::vector ¤t_external_libs) { RecheckChanged(previous_external_libs, current_external_libs, std::bind(&Target::ExternalLibChanged, this)); } diff --git a/buildcc/lib/target/src/target/target_loader.cpp b/buildcc/lib/target/src/target/target_loader.cpp deleted file mode 100644 index 35d40d13..00000000 --- a/buildcc/lib/target/src/target/target_loader.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/base/target_loader.h" - -#include "env/logging.h" -#include "env/util.h" - -// Private -#include "target/private/schema_util.h" -#include "target_generated.h" - -namespace buildcc::internal { - -// Public functions -bool TargetLoader::Load() { - env::log_trace(name_, __FUNCTION__); - - auto file_path = GetBinaryPath(); - std::string buffer; - bool is_loaded = - env::load_file(path_as_string(file_path).c_str(), true, &buffer); - if (!is_loaded) { - return false; - } - - flatbuffers::Verifier verifier((const uint8_t *)buffer.c_str(), - buffer.length()); - const bool is_verified = fbs::VerifyTargetBuffer(verifier); - if (!is_verified) { - return false; - } - - const auto *target = fbs::GetTarget((const void *)buffer.c_str()); - // target->name()->c_str(); - // target->type(); - - extract_path(target->source_files(), loaded_sources_); - extract_path(target->header_files(), loaded_headers_); - extract_path(target->pch_files(), loaded_pchs_); - extract_path(target->lib_deps(), loaded_lib_deps_); - - extract(target->external_lib_deps(), loaded_external_lib_dirs_); - - extract(target->include_dirs(), loaded_include_dirs_); - extract(target->lib_dirs(), loaded_lib_dirs_); - - extract(target->preprocessor_flags(), loaded_preprocessor_flags_); - extract(target->common_compile_flags(), loaded_common_compile_flags_); - extract(target->pch_compile_flags(), loaded_pch_compile_flags_); - extract(target->pch_object_flags(), loaded_pch_object_flags_); - extract(target->asm_compile_flags(), loaded_asm_compile_flags_); - extract(target->c_compile_flags(), loaded_c_compile_flags_); - extract(target->cpp_compile_flags(), loaded_cpp_compile_flags_); - extract(target->link_flags(), loaded_link_flags_); - - extract_path(target->compile_dependencies(), loaded_compile_dependencies_); - extract_path(target->link_dependencies(), loaded_link_dependencies_); - - loaded_pch_compiled_ = target->pch_compiled(); - loaded_target_linked_ = target->target_linked(); - - loaded_ = true; - return true; -} - -// Private functions -void TargetLoader::Initialize() {} - -} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/target/target_serialization.cpp b/buildcc/lib/target/src/target/target_serialization.cpp new file mode 100644 index 00000000..b965ae56 --- /dev/null +++ b/buildcc/lib/target/src/target/target_serialization.cpp @@ -0,0 +1,153 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "target/serialization/target_serialization.h" + +// Third party +#include "flatbuffers/flatbuffers.h" + +// Private +#include "target/private/schema_util.h" + +// Schema generated +#include "target_generated.h" + +namespace buildcc::internal { + +// PUBLIC +void TargetSerialization::UpdatePchCompiled(const TargetSchema &store) { + store_.internal_pchs = store.internal_pchs; + store_.pch_compiled = true; +} +void TargetSerialization::AddSource(const internal::Path &source) { + std::lock_guard guard(add_source_mutex); + store_.internal_sources.insert(source); +} + +void TargetSerialization::UpdateTargetCompiled() { + store_.target_linked = true; +} + +void TargetSerialization::UpdateStore(const TargetSchema &store) { + TargetSchema temp = store; + temp.internal_pchs = store_.internal_pchs; + temp.pch_compiled = store_.pch_compiled; + temp.internal_sources = store_.internal_sources; + temp.target_linked = store_.target_linked; + store_ = std::move(temp); +} + +// PRIVATE +bool TargetSerialization::Verify(const std::string &serialized_data) { + flatbuffers::Verifier verifier((const uint8_t *)serialized_data.c_str(), + serialized_data.length()); + return fbs::VerifyTargetBuffer(verifier); +} + +bool TargetSerialization::Load(const std::string &serialized_data) { + const auto *target = fbs::GetTarget((const void *)serialized_data.c_str()); + if (target == nullptr) { + return false; + } + + extract_path(target->source_files(), load_.internal_sources); + extract_path(target->header_files(), load_.internal_headers); + extract_path(target->pch_files(), load_.internal_pchs); + extract_path(target->lib_deps(), load_.internal_libs); + + extract(target->external_lib_deps(), load_.external_libs); + + extract(target->include_dirs(), load_.include_dirs); + extract(target->lib_dirs(), load_.lib_dirs); + + extract(target->preprocessor_flags(), load_.preprocessor_flags); + extract(target->common_compile_flags(), load_.common_compile_flags); + extract(target->pch_compile_flags(), load_.pch_compile_flags); + extract(target->pch_object_flags(), load_.pch_object_flags); + extract(target->asm_compile_flags(), load_.asm_compile_flags); + extract(target->c_compile_flags(), load_.c_compile_flags); + extract(target->cpp_compile_flags(), load_.cpp_compile_flags); + extract(target->link_flags(), load_.link_flags); + + extract_path(target->compile_dependencies(), + load_.internal_compile_dependencies); + extract_path(target->link_dependencies(), load_.internal_link_dependencies); + + load_.pch_compiled = target->pch_compiled(); + load_.target_linked = target->target_linked(); + return true; +} + +bool TargetSerialization::Store(const fs::path &absolute_serialized_file) { + flatbuffers::FlatBufferBuilder builder; + + auto fbs_target_type = (fbs::TargetType)store_.type; + + auto fbs_source_files = + internal::create_fbs_vector_path(builder, store_.internal_sources); + auto fbs_header_files = + internal::create_fbs_vector_path(builder, store_.internal_headers); + auto fbs_pch_files = + internal::create_fbs_vector_path(builder, store_.internal_pchs); + + auto fbs_lib_deps = + internal::create_fbs_vector_path(builder, store_.internal_libs); + auto fbs_external_lib_deps = + internal::create_fbs_vector_string(builder, store_.external_libs); + + auto fbs_include_dirs = + internal::create_fbs_vector_string(builder, store_.include_dirs); + auto fbs_lib_dirs = + internal::create_fbs_vector_string(builder, store_.lib_dirs); + + auto fbs_preprocessor_flags = + internal::create_fbs_vector_string(builder, store_.preprocessor_flags); + auto fbs_common_compile_flags = + internal::create_fbs_vector_string(builder, store_.common_compile_flags); + auto fbs_pch_compile_flags = + internal::create_fbs_vector_string(builder, store_.pch_compile_flags); + auto fbs_pch_object_flags = + internal::create_fbs_vector_string(builder, store_.pch_object_flags); + auto fbs_asm_compile_flags = + internal::create_fbs_vector_string(builder, store_.asm_compile_flags); + auto fbs_c_compile_flags = + internal::create_fbs_vector_string(builder, store_.c_compile_flags); + auto fbs_cpp_compile_flags = + internal::create_fbs_vector_string(builder, store_.cpp_compile_flags); + auto fbs_link_flags = + internal::create_fbs_vector_string(builder, store_.link_flags); + + auto fbs_compile_dependencies = internal::create_fbs_vector_path( + builder, store_.internal_compile_dependencies); + auto fbs_link_dependencies = internal::create_fbs_vector_path( + builder, store_.internal_link_dependencies); + + auto fbs_target = fbs::CreateTargetDirect( + builder, store_.name.c_str(), fbs_target_type, &fbs_source_files, + &fbs_header_files, &fbs_pch_files, &fbs_lib_deps, &fbs_external_lib_deps, + &fbs_include_dirs, &fbs_lib_dirs, &fbs_preprocessor_flags, + &fbs_common_compile_flags, &fbs_pch_compile_flags, &fbs_pch_object_flags, + &fbs_asm_compile_flags, &fbs_c_compile_flags, &fbs_cpp_compile_flags, + &fbs_link_flags, &fbs_compile_dependencies, &fbs_link_dependencies, + store_.pch_compiled, store_.target_linked); + fbs::FinishTargetBuffer(builder, fbs_target); + + return env::save_file(path_as_string(absolute_serialized_file).c_str(), + (const char *)builder.GetBufferPointer(), + builder.GetSize(), true); +} + +} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/target/target_storer.cpp b/buildcc/lib/target/src/target/target_storer.cpp deleted file mode 100644 index 65793748..00000000 --- a/buildcc/lib/target/src/target/target_storer.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/target.h" - -#include -#include - -#include "env/logging.h" -#include "env/util.h" - -#include "target/private/schema_util.h" -#include "target_generated.h" - -namespace fbs = schema::internal; - -namespace { - -fbs::TargetType CreateFbsTargetType(buildcc::TargetType type) { - return (fbs::TargetType)type; -} - -} // namespace - -namespace buildcc { - -bool Target::Store() { - env::log_trace(name_, __FUNCTION__); - - flatbuffers::FlatBufferBuilder builder; - - auto fbs_target_type = CreateFbsTargetType(type_); - - auto fbs_source_files = internal::create_fbs_vector_path( - builder, storer_.current_source_files.internal); - auto fbs_header_files = internal::create_fbs_vector_path( - builder, storer_.current_header_files.internal); - auto fbs_pch_files = internal::create_fbs_vector_path( - builder, storer_.current_pch_files.internal); - // NOTE, This can be UNORDERED - auto fbs_lib_deps = internal::create_fbs_vector_path( - builder, storer_.current_internal_lib_deps); - - // NOTE, This can be UNORDERED - auto fbs_external_lib_deps = internal::create_fbs_vector_string( - builder, storer_.current_internal_external_lib_deps); - - auto fbs_include_dirs = - internal::create_fbs_vector_string(builder, storer_.current_include_dirs); - auto fbs_lib_dirs = - internal::create_fbs_vector_string(builder, storer_.current_lib_dirs); - - auto fbs_preprocessor_flags = internal::create_fbs_vector_string( - builder, storer_.current_preprocessor_flags); - auto fbs_common_compile_flags = internal::create_fbs_vector_string( - builder, storer_.current_common_compile_flags); - auto fbs_pch_compile_flags = internal::create_fbs_vector_string( - builder, storer_.current_pch_compile_flags); - auto fbs_pch_object_flags = internal::create_fbs_vector_string( - builder, storer_.current_pch_object_flags); - auto fbs_asm_compile_flags = internal::create_fbs_vector_string( - builder, storer_.current_asm_compile_flags); - auto fbs_c_compile_flags = internal::create_fbs_vector_string( - builder, storer_.current_c_compile_flags); - auto fbs_cpp_compile_flags = internal::create_fbs_vector_string( - builder, storer_.current_cpp_compile_flags); - auto fbs_link_flags = - internal::create_fbs_vector_string(builder, storer_.current_link_flags); - - auto fbs_compile_dependencies = internal::create_fbs_vector_path( - builder, storer_.current_compile_dependencies.internal); - auto fbs_link_dependencies = internal::create_fbs_vector_path( - builder, storer_.current_link_dependencies.internal); - - auto fbs_target = fbs::CreateTargetDirect( - builder, name_.c_str(), fbs_target_type, &fbs_source_files, - &fbs_header_files, &fbs_pch_files, &fbs_lib_deps, &fbs_external_lib_deps, - &fbs_include_dirs, &fbs_lib_dirs, &fbs_preprocessor_flags, - &fbs_common_compile_flags, &fbs_pch_compile_flags, &fbs_pch_object_flags, - &fbs_asm_compile_flags, &fbs_c_compile_flags, &fbs_cpp_compile_flags, - &fbs_link_flags, &fbs_compile_dependencies, &fbs_link_dependencies, - storer_.pch_compiled, storer_.target_linked); - fbs::FinishTargetBuffer(builder, fbs_target); - - auto file_path = GetBinaryPath(); - return env::save_file(path_as_string(file_path).c_str(), - (const char *)builder.GetBufferPointer(), - builder.GetSize(), true); -} - -} // namespace buildcc diff --git a/buildcc/lib/target/src/target/tasks.cpp b/buildcc/lib/target/src/target/tasks.cpp index 772d31e9..94b81ec7 100644 --- a/buildcc/lib/target/src/target/tasks.cpp +++ b/buildcc/lib/target/src/target/tasks.cpp @@ -80,6 +80,7 @@ void CompilePch::Task() { task_ = target_.tf_.emplace([&](tf::Subflow &subflow) { try { BuildCompile(); + target_.serialization_.UpdatePchCompiled(target_.user_); } catch (...) { target_.SetTaskStateFailure(); } @@ -111,9 +112,9 @@ void CompileObject::Task() { try { BuildObjectCompile(selected_source_files, selected_dummy_source_files); - target_.compiled_source_files_.clear(); - target_.compiled_source_files_.insert(selected_dummy_source_files.begin(), - selected_dummy_source_files.end()); + for (const auto &piter : selected_dummy_source_files) { + target_.serialization_.AddSource(piter); + } for (const auto &s : selected_source_files) { std::string name = fmt::format("{}", s.GetPathname().lexically_relative( @@ -124,17 +125,9 @@ void CompileObject::Task() { bool success = env::Command::Execute( GetObjectData(s.GetPathname()).command); env::assert_throw(success, "Could not compile source"); - - // NOTE, If conmpilation is successful we update the source - // files - std::lock_guard guard( - target_.compiled_source_files_mutex_); - target_.compiled_source_files_.insert(s); + target_.serialization_.AddSource(s); } catch (...) { target_.SetTaskStateFailure(); - - // NOTE, If compilation fails, we do not need to update the - // source files } }) .name(name); @@ -177,8 +170,8 @@ void Target::EndTask() { target_end_task_ = tf_.emplace([&]() { if (dirty_) { try { - storer_.current_source_files.internal = compiled_source_files_; - env::assert_throw(Store(), + serialization_.UpdateStore(user_); + env::assert_throw(serialization_.StoreToFile(), fmt::format("Store failed for {}", GetName())); state_.build = true; } catch (...) { diff --git a/buildcc/lib/target/test/target/CMakeLists.txt b/buildcc/lib/target/test/target/CMakeLists.txt index 2797dfc6..9b914b55 100644 --- a/buildcc/lib/target/test/target/CMakeLists.txt +++ b/buildcc/lib/target/test/target/CMakeLists.txt @@ -14,7 +14,15 @@ add_executable(test_builder_interface ) target_link_libraries(test_builder_interface PRIVATE target_interface) +add_executable(test_serialization_interface + test_serialization_interface.cpp +) +target_link_libraries(test_serialization_interface PRIVATE target_interface) + add_test(NAME test_builder_interface COMMAND test_builder_interface) +add_test(NAME test_serialization_interface COMMAND test_serialization_interface + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) # Common add_executable(test_target_config diff --git a/buildcc/lib/target/test/target/test_builder_interface.cpp b/buildcc/lib/target/test/target/test_builder_interface.cpp index 8c832b36..84c14749 100644 --- a/buildcc/lib/target/test/target/test_builder_interface.cpp +++ b/buildcc/lib/target/test/target/test_builder_interface.cpp @@ -32,7 +32,6 @@ class TestBuilderInterface : public buildcc::internal::BuilderInterface { } private: - bool Store() override { return false; } buildcc::internal::path_unordered_set previous_; buildcc::internal::path_unordered_set current_; }; diff --git a/buildcc/lib/target/test/target/test_serialization_interface.cpp b/buildcc/lib/target/test/target/test_serialization_interface.cpp new file mode 100644 index 00000000..b5083059 --- /dev/null +++ b/buildcc/lib/target/test/target/test_serialization_interface.cpp @@ -0,0 +1,115 @@ +#include "target/interface/serialization_interface.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +class TestSerializationInterface + : public buildcc::internal::SerializationInterface { +public: + TestSerializationInterface(const fs::path &serialized_file) + : SerializationInterface(serialized_file) {} + + void VerifyExpectation(int calls, bool return_value) { + mock() + .expectNCalls(calls, "verify") + .onObject(this) + .andReturnValue(return_value); + } + + void LoadExpectation(int calls, bool return_value) { + mock() + .expectNCalls(calls, "load") + .onObject(this) + .andReturnValue(return_value); + } + + void StoreExpectation(int calls, bool return_value) { + mock() + .expectNCalls(calls, "store") + .onObject(this) + .andReturnValue(return_value); + } + +private: + bool Verify(const std::string &serialized_data) override { + (void)serialized_data; + return mock().actualCall("verify").onObject(this).returnBoolValue(); + } + + bool Load(const std::string &serialized_data) override { + (void)serialized_data; + return mock().actualCall("load").onObject(this).returnBoolValue(); + } + + bool Store(const fs::path &absolute_serialized_file) override { + (void)absolute_serialized_file; + return mock().actualCall("store").onObject(this).returnBoolValue(); + } +}; + +// clang-format off +TEST_GROUP(TestSerializationInterfaceGroup) +{ + void teardown() { + mock().clear(); + } +}; +// clang-format on + +TEST(TestSerializationInterfaceGroup, Verify_False) { + TestSerializationInterface test_serialization_interface( + fs::current_path() / "data" / "dummy_main.c"); + + test_serialization_interface.VerifyExpectation(1, false); + bool loaded = test_serialization_interface.LoadFromFile(); + CHECK_FALSE(loaded); +} + +TEST(TestSerializationInterfaceGroup, Load_False) { + TestSerializationInterface test_serialization_interface( + fs::current_path() / "data" / "dummy_main.c"); + + test_serialization_interface.VerifyExpectation(1, true); + test_serialization_interface.LoadExpectation(1, false); + bool loaded = test_serialization_interface.LoadFromFile(); + CHECK_FALSE(loaded); +} + +TEST(TestSerializationInterfaceGroup, Load_True) { + TestSerializationInterface test_serialization_interface( + fs::current_path() / "data" / "dummy_main.c"); + + test_serialization_interface.VerifyExpectation(1, true); + test_serialization_interface.LoadExpectation(1, true); + bool loaded = test_serialization_interface.LoadFromFile(); + CHECK_TRUE(loaded); +} + +TEST(TestSerializationInterfaceGroup, Store_False) { + TestSerializationInterface test_serialization_interface( + fs::current_path() / "data" / "dummy_main.c"); + test_serialization_interface.StoreExpectation(1, false); + bool stored = test_serialization_interface.StoreToFile(); + CHECK_FALSE(stored); +} + +TEST(TestSerializationInterfaceGroup, Store_True) { + TestSerializationInterface test_serialization_interface( + fs::current_path() / "data" / "dummy_main.c"); + test_serialization_interface.StoreExpectation(1, true); + bool stored = test_serialization_interface.StoreToFile(); + CHECK_TRUE(stored); + + std::string serialized_file = + test_serialization_interface.GetSerializedFile().string(); + std::string compare = (fs::current_path() / "data" / "dummy_main.c").string(); + STRCMP_EQUAL(serialized_file.c_str(), compare.c_str()); +} + +int main(int ac, char **av) { + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/lib/target/test/target/test_target_external_lib.cpp b/buildcc/lib/target/test/target/test_target_external_lib.cpp index 8500de88..72e7dcdf 100644 --- a/buildcc/lib/target/test/target/test_target_external_lib.cpp +++ b/buildcc/lib/target/test/target/test_target_external_lib.cpp @@ -7,7 +7,7 @@ #include "target/target.h" -#include "target/base/target_loader.h" +#include "target/serialization/target_serialization.h" #include #include @@ -53,12 +53,12 @@ TEST(TargetTestExternalLib, TestAddLibDir) { mock().checkExpectations(); // Verify binary - buildcc::internal::TargetLoader loader(EXENAME, exe.GetTargetBuildDir()); - bool loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + exe.GetTargetBuildDir() / (std::string(EXENAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - - CHECK_EQUAL(loader.GetLoadedLibDirs().size(), 1); - CHECK_EQUAL(loader.GetLoadedExternalLibDeps().size(), 0); + CHECK_EQUAL(serialization.GetLoad().lib_dirs.size(), 1); + CHECK_EQUAL(serialization.GetLoad().external_libs.size(), 0); } TEST(TargetTestExternalLib, TestAddExternalLibDep_Simple) { @@ -81,12 +81,13 @@ TEST(TargetTestExternalLib, TestAddExternalLibDep_Simple) { mock().checkExpectations(); // Verify binary - buildcc::internal::TargetLoader loader(EXENAME, exe.GetTargetBuildDir()); - bool loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + exe.GetTargetBuildDir() / (std::string(EXENAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(loader.GetLoadedLibDirs().size(), 1); - CHECK_EQUAL(loader.GetLoadedExternalLibDeps().size(), 1); + CHECK_EQUAL(serialization.GetLoad().lib_dirs.size(), 1); + CHECK_EQUAL(serialization.GetLoad().external_libs.size(), 1); } TEST(TargetTestExternalLib, TestAddExternalLibDep_RebuildChanged) { diff --git a/buildcc/lib/target/test/target/test_target_failure_states.cpp b/buildcc/lib/target/test/target/test_target_failure_states.cpp index 4b9bac5a..bfe00ed9 100644 --- a/buildcc/lib/target/test/target/test_target_failure_states.cpp +++ b/buildcc/lib/target/test/target/test_target_failure_states.cpp @@ -193,6 +193,7 @@ TEST(TargetTestFailureStates, CompilePchFailure_Rebuild) { target.AddPch("include/include_header.h"); target.Build(); + buildcc::m::TargetExpect_PathAdded(1, &target); buildcc::env::m::CommandExpect_Execute(1, true); // PCH compile buildcc::env::m::CommandExpect_Execute(1, true); // Object compile buildcc::env::m::CommandExpect_Execute(1, true); // Link target diff --git a/buildcc/lib/target/test/target/test_target_flags.cpp b/buildcc/lib/target/test/target/test_target_flags.cpp index 8b6cb218..21acef59 100644 --- a/buildcc/lib/target/test/target/test_target_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_flags.cpp @@ -8,7 +8,7 @@ #include "env/env.h" // -#include "target/base/target_loader.h" +#include "target/serialization/target_serialization.h" // Third Party @@ -62,11 +62,12 @@ TEST(TargetTestPreprocessorFlagGroup, Target_AddPreprocessorFlag) { mock().checkExpectations(); // Verify binary - buildcc::internal::TargetLoader loader(NAME, simple.GetTargetBuildDir()); - bool loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(loader.GetLoadedPreprocessorFlags().size(), 1); + CHECK_EQUAL(serialization.GetLoad().preprocessor_flags.size(), 1); } TEST(TargetTestPreprocessorFlagGroup, Target_ChangedPreprocessorFlag) { @@ -160,11 +161,12 @@ TEST(TargetTestCommonCompileFlagsGroup, Target_AddCommonCompileFlag) { mock().checkExpectations(); // Verify binary - buildcc::internal::TargetLoader loader(NAME, simple.GetTargetBuildDir()); - bool loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(loader.GetLoadedCommonCompileFlags().size(), 2); + CHECK_EQUAL(serialization.GetLoad().common_compile_flags.size(), 2); } TEST(TargetTestCommonCompileFlagsGroup, Target_ChangedCommonCompileFlag) { @@ -274,11 +276,12 @@ TEST(TargetTestAsmCompileFlagGroup, Target_AddCompileFlag) { mock().checkExpectations(); // Verify binary - buildcc::internal::TargetLoader loader(NAME, simple.GetTargetBuildDir()); - bool loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(loader.GetLoadedAsmCompileFlags().size(), 2); + CHECK_EQUAL(serialization.GetLoad().asm_compile_flags.size(), 2); } TEST(TargetTestAsmCompileFlagGroup, Target_ChangedCompileFlag) { @@ -388,11 +391,12 @@ TEST(TargetTestCCompileFlagsGroup, Target_AddCompileFlag) { mock().checkExpectations(); // Verify binary - buildcc::internal::TargetLoader loader(NAME, simple.GetTargetBuildDir()); - bool loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(loader.GetLoadedCCompileFlags().size(), 1); + CHECK_EQUAL(serialization.GetLoad().c_compile_flags.size(), 1); } TEST(TargetTestCCompileFlagsGroup, Target_ChangedCompileFlag) { @@ -485,11 +489,12 @@ TEST(TargetTestCppCompileFlagsGroup, Target_AddCompileFlag) { mock().checkExpectations(); // Verify binary - buildcc::internal::TargetLoader loader(NAME, simple.GetTargetBuildDir()); - bool loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(loader.GetLoadedCppCompileFlags().size(), 1); + CHECK_EQUAL(serialization.GetLoad().cpp_compile_flags.size(), 1); } TEST(TargetTestCppCompileFlagsGroup, Target_ChangedCompileFlag) { @@ -582,11 +587,12 @@ TEST(TargetTestLinkFlagsGroup, Target_AddLinkFlag) { mock().checkExpectations(); // Verify binary - buildcc::internal::TargetLoader loader(NAME, simple.GetTargetBuildDir()); - bool loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(loader.GetLoadedLinkFlags().size(), 1); + CHECK_EQUAL(serialization.GetLoad().link_flags.size(), 1); } TEST(TargetTestLinkFlagsGroup, Target_ChangedLinkFlag) { diff --git a/buildcc/lib/target/test/target/test_target_include_dir.cpp b/buildcc/lib/target/test/target/test_target_include_dir.cpp index 2a65112a..323a6935 100644 --- a/buildcc/lib/target/test/target/test_target_include_dir.cpp +++ b/buildcc/lib/target/test/target/test_target_include_dir.cpp @@ -114,11 +114,12 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { include_compile.Build(); buildcc::m::TargetRunner(include_compile); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + intermediate_path / (std::string(NAME) + ".bin")); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = loader.GetLoadedSources(); - const auto &loaded_dirs = loader.GetLoadedIncludeDirs(); + const auto &loaded_sources = serialization.GetLoad().internal_sources; + const auto &loaded_dirs = serialization.GetLoad().include_dirs; CHECK_EQUAL(loaded_sources.size(), 2); CHECK_EQUAL(loaded_dirs.size(), 1); @@ -146,11 +147,12 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { include_compile.Build(); buildcc::m::TargetRunner(include_compile); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + intermediate_path / (std::string(NAME) + ".bin")); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = loader.GetLoadedSources(); - const auto &loaded_dirs = loader.GetLoadedIncludeDirs(); + const auto &loaded_sources = serialization.GetLoad().internal_sources; + const auto &loaded_dirs = serialization.GetLoad().include_dirs; CHECK_EQUAL(loaded_sources.size(), 2); CHECK_EQUAL(loaded_dirs.size(), 2); @@ -175,11 +177,12 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { include_compile.Build(); buildcc::m::TargetRunner(include_compile); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + intermediate_path / (std::string(NAME) + ".bin")); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = loader.GetLoadedSources(); - const auto &loaded_dirs = loader.GetLoadedIncludeDirs(); + const auto &loaded_sources = serialization.GetLoad().internal_sources; + const auto &loaded_dirs = serialization.GetLoad().include_dirs; CHECK_EQUAL(loaded_sources.size(), 2); CHECK_EQUAL(loaded_dirs.size(), 1); @@ -228,12 +231,13 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { add_header.Build(); buildcc::m::TargetRunner(add_header); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + intermediate_path / (std::string(NAME) + ".bin")); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - CHECK_EQUAL(loader.GetLoadedSources().size(), 2); - CHECK_EQUAL(loader.GetLoadedIncludeDirs().size(), 1); - CHECK_EQUAL(loader.GetLoadedHeaders().size(), 0); + CHECK_EQUAL(serialization.GetLoad().internal_sources.size(), 2); + CHECK_EQUAL(serialization.GetLoad().include_dirs.size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_headers.size(), 0); } // Add header @@ -251,12 +255,13 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { add_header.Build(); buildcc::m::TargetRunner(add_header); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + intermediate_path / (std::string(NAME) + ".bin")); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - CHECK_EQUAL(loader.GetLoadedSources().size(), 2); - CHECK_EQUAL(loader.GetLoadedIncludeDirs().size(), 1); - CHECK_EQUAL(loader.GetLoadedHeaders().size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_sources.size(), 2); + CHECK_EQUAL(serialization.GetLoad().include_dirs.size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_headers.size(), 1); } // Update header @@ -280,12 +285,13 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { add_header.Build(); buildcc::m::TargetRunner(add_header); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + intermediate_path / (std::string(NAME) + ".bin")); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - CHECK_EQUAL(loader.GetLoadedSources().size(), 2); - CHECK_EQUAL(loader.GetLoadedIncludeDirs().size(), 1); - CHECK_EQUAL(loader.GetLoadedHeaders().size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_sources.size(), 2); + CHECK_EQUAL(serialization.GetLoad().include_dirs.size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_headers.size(), 1); } // Remove header @@ -302,12 +308,13 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { add_header.Build(); buildcc::m::TargetRunner(add_header); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + intermediate_path / (std::string(NAME) + ".bin")); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - CHECK_EQUAL(loader.GetLoadedSources().size(), 2); - CHECK_EQUAL(loader.GetLoadedIncludeDirs().size(), 1); - CHECK_EQUAL(loader.GetLoadedHeaders().size(), 0); + CHECK_EQUAL(serialization.GetLoad().internal_sources.size(), 2); + CHECK_EQUAL(serialization.GetLoad().include_dirs.size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_headers.size(), 0); } mock().checkExpectations(); diff --git a/buildcc/lib/target/test/target/test_target_lib_dep.cpp b/buildcc/lib/target/test/target/test_target_lib_dep.cpp index 4d2cf140..f9ff8faf 100644 --- a/buildcc/lib/target/test/target/test_target_lib_dep.cpp +++ b/buildcc/lib/target/test/target/test_target_lib_dep.cpp @@ -9,7 +9,7 @@ #include "target/target.h" // -#include "target/base/target_loader.h" +#include "target/serialization/target_serialization.h" #include #include @@ -54,13 +54,13 @@ TEST(TargetTestLibDep, StaticLibrary_SimpleBuildTest) { mock().checkExpectations(); // Verify binary - buildcc::internal::TargetLoader loader(STATIC_NAME, - foolib.GetTargetBuildDir()); - bool loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + foolib.GetTargetBuildDir() / (std::string(STATIC_NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(loader.GetLoadedSources().size(), 1); - CHECK_EQUAL(loader.GetLoadedIncludeDirs().size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_sources.size(), 1); + CHECK_EQUAL(serialization.GetLoad().include_dirs.size(), 1); } TEST(TargetTestLibDep, TargetDep_RebuildTest) { diff --git a/buildcc/lib/target/test/target/test_target_source.cpp b/buildcc/lib/target/test/target/test_target_source.cpp index c68f6ea4..f2664083 100644 --- a/buildcc/lib/target/test/target/test_target_source.cpp +++ b/buildcc/lib/target/test/target/test_target_source.cpp @@ -107,11 +107,11 @@ TEST(TargetTestSourceGroup, Target_Build_SourceCompile) { mock().checkExpectations(); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization(simple.GetBinaryPath()); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = loader.GetLoadedSources(); + const auto &loaded_sources = serialization.GetLoad().internal_sources; CHECK_EQUAL(loaded_sources.size(), 1); auto dummy_file = buildcc::internal::Path::CreateExistingPath( (source_path / DUMMY_MAIN).make_preferred().string()); @@ -150,11 +150,12 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { simple.Build(); buildcc::m::TargetRunner(simple); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + simple.GetBinaryPath()); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = loader.GetLoadedSources(); + const auto &loaded_sources = serialization.GetLoad().internal_sources; CHECK_EQUAL(loaded_sources.size(), 2); CHECK_FALSE(loaded_sources.find(dummy_c_file) == loaded_sources.end()); @@ -181,11 +182,12 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { simple.Build(); buildcc::m::TargetRunner(simple); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + simple.GetBinaryPath()); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = loader.GetLoadedSources(); + const auto &loaded_sources = serialization.GetLoad().internal_sources; CHECK_EQUAL(loaded_sources.size(), 2); CHECK_FALSE(loaded_sources.find(dummy_cpp_file) == loaded_sources.end()); CHECK_FALSE(loaded_sources.find(new_source_file) == loaded_sources.end()); @@ -211,11 +213,12 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { simple.Build(); buildcc::m::TargetRunner(simple); - buildcc::internal::TargetLoader loader(NAME, intermediate_path); - bool is_loaded = loader.Load(); + buildcc::internal::TargetSerialization serialization( + simple.GetBinaryPath()); + bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = loader.GetLoadedSources(); + const auto &loaded_sources = serialization.GetLoad().internal_sources; CHECK_EQUAL(loaded_sources.size(), 2); CHECK_FALSE(loaded_sources.find(dummy_cpp_file) == loaded_sources.end()); CHECK_FALSE(loaded_sources.find(new_source_file) == loaded_sources.end()); diff --git a/buildexe/src/toolchain_setup.cpp b/buildexe/src/toolchain_setup.cpp index e9bfe0e1..198bf40d 100644 --- a/buildexe/src/toolchain_setup.cpp +++ b/buildexe/src/toolchain_setup.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "buildexe/toolchain_setup.h" + namespace { constexpr const char *const kTag = "BuildExe"; From 2dedb35a02db06799fddb6fff909b09e01c0e815 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 13 Feb 2022 00:02:27 -0800 Subject: [PATCH 02/35] Serialization common (#193) --- bootstrap/src/build_buildcc.cpp | 9 +- buildcc/CMakeLists.txt | 6 +- .../lib/target/cmake/common_target_src.cmake | 14 +-- buildcc/lib/target/cmake/mock_target.cmake | 5 +- buildcc/lib/target/cmake/target.cmake | 11 +-- .../target/include/target/api/target_getter.h | 2 +- .../include/target/api/target_info_getter.h | 2 +- .../lib/target/include/target/common/util.h | 2 +- .../include/target/friend/compile_object.h | 2 +- buildcc/lib/target/include/target/generator.h | 4 +- .../target/interface/builder_interface.h | 1 - buildcc/lib/target/include/target/target.h | 6 +- .../lib/target/include/target/target_info.h | 2 +- .../lib/target/src/common/target_config.cpp | 2 +- .../target/src/target/friend/compile_pch.cpp | 2 +- buildcc/lib/target/test/path/CMakeLists.txt | 4 +- buildcc/lib/target/test/path/test_path.cpp | 2 +- .../test/target/test_builder_interface.cpp | 2 +- .../target/test_serialization_interface.cpp | 2 +- .../test/target/test_target_external_lib.cpp | 2 +- .../target/test/target/test_target_flags.cpp | 2 +- .../test/target/test_target_lib_dep.cpp | 2 +- buildcc/plugins/src/buildcc_find.cpp | 2 +- buildcc/schema/CMakeLists.txt | 28 +----- buildcc/schema/cmake/schema.cmake | 89 ++++++++++++++++++ buildcc/schema/cmake/schema_generate.cmake | 26 +++++ .../include/schema}/generator_serialization.h | 10 +- .../interface/serialization_interface.h | 6 +- .../common => schema/include/schema}/path.h | 4 +- .../include/schema}/private/schema_util.h | 6 +- .../include/schema}/target_serialization.h | 12 +-- .../include/schema}/target_type.h | 4 +- .../src}/generator_serialization.cpp | 4 +- .../src}/target_serialization.cpp | 4 +- .../buildcc_interface_lib.PNG | Bin 144041 -> 142148 bytes .../buildcc_single_lib.PNG | Bin 126774 -> 132243 bytes docs/source/arch/project_layout.rst | 14 ++- docs/source/arch/software_heirarchy.rst | 11 ++- 38 files changed, 193 insertions(+), 113 deletions(-) create mode 100644 buildcc/schema/cmake/schema.cmake create mode 100644 buildcc/schema/cmake/schema_generate.cmake rename buildcc/{lib/target/include/target/serialization => schema/include/schema}/generator_serialization.h (88%) rename buildcc/{lib/target/include/target => schema/include/schema}/interface/serialization_interface.h (93%) rename buildcc/{lib/target/include/target/common => schema/include/schema}/path.h (98%) rename buildcc/{lib/target/include/target => schema/include/schema}/private/schema_util.h (97%) rename buildcc/{lib/target/include/target/serialization => schema/include/schema}/target_serialization.h (91%) rename buildcc/{lib/target/include/target/common => schema/include/schema}/target_type.h (91%) rename buildcc/{lib/target/src/generator => schema/src}/generator_serialization.cpp (95%) rename buildcc/{lib/target/src/target => schema/src}/target_serialization.cpp (98%) diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index fd538a3b..33b1066b 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -53,6 +53,13 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, target.AddIncludeDir("lib/env/include"); target.GlobHeaders("lib/env/include/env"); + // SCHEMA + target.GlobSources("schema/src"); + target.AddIncludeDir("schema/include"); + target.GlobHeaders("schema/include/schema"); + target.GlobHeaders("schema/include/schema/interface"); + target.GlobHeaders("schema/include/schema/private"); + // TOOLCHAIN target.GlobSources("lib/toolchain/src/api"); target.AddIncludeDir("lib/toolchain/include"); @@ -72,8 +79,6 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, target.GlobHeaders("lib/target/include/target/common"); target.GlobHeaders("lib/target/include/target/friend"); target.GlobHeaders("lib/target/include/target/interface"); - target.GlobHeaders("lib/target/include/target/private"); - target.GlobHeaders("lib/target/include/target/serialization"); // ARGS target.GlobSources("lib/args/src"); diff --git a/buildcc/CMakeLists.txt b/buildcc/CMakeLists.txt index 860404be..f4d5d628 100644 --- a/buildcc/CMakeLists.txt +++ b/buildcc/CMakeLists.txt @@ -2,9 +2,6 @@ set(BUILDCC_INSTALL_LIB_PREFIX "lib/cmake") set(BUILDCC_INSTALL_HEADER_PREFIX "include/buildcc") -# Flatbuffers schema -add_subdirectory(schema) - if(${BUILDCC_BUILD_AS_SINGLE_LIB}) add_library(buildcc STATIC buildcc.h @@ -31,6 +28,9 @@ if(${BUILDCC_BUILD_AS_SINGLE_LIB}) endif() endif() +# Flatbuffers schema +add_subdirectory(schema) + # Environment add_subdirectory(lib/env) diff --git a/buildcc/lib/target/cmake/common_target_src.cmake b/buildcc/lib/target/cmake/common_target_src.cmake index 88ec2a02..875e5edf 100644 --- a/buildcc/lib/target/cmake/common_target_src.cmake +++ b/buildcc/lib/target/cmake/common_target_src.cmake @@ -1,22 +1,18 @@ set(COMMON_TARGET_SRCS # Interfaces include/target/interface/builder_interface.h - include/target/interface/serialization_interface.h # Common src/common/target_config.cpp src/common/target_state.cpp - include/target/common/target_file_ext.h include/target/common/target_config.h include/target/common/target_state.h + include/target/common/target_file_ext.h include/target/common/target_env.h - include/target/common/target_type.h src/common/util.cpp include/target/common/util.h - include/target/common/path.h - # API src/api/source_api.cpp src/api/include_api.cpp @@ -39,10 +35,6 @@ set(COMMON_TARGET_SRCS include/target/api/target_info_getter.h include/target/api/target_getter.h - # Base Generator - src/generator/generator_serialization.cpp - include/target/serialization/generator_serialization.h - # Generator src/generator/generator.cpp include/target/generator.h @@ -55,10 +47,6 @@ set(COMMON_TARGET_SRCS include/target/friend/compile_object.h include/target/friend/link_target.h - # Base Target - src/target/target_serialization.cpp - include/target/serialization/target_serialization.h - # Target src/target/target.cpp src/target/build.cpp diff --git a/buildcc/lib/target/cmake/mock_target.cmake b/buildcc/lib/target/cmake/mock_target.cmake index 367fc0ac..da18b626 100644 --- a/buildcc/lib/target/cmake/mock_target.cmake +++ b/buildcc/lib/target/cmake/mock_target.cmake @@ -14,15 +14,14 @@ add_library(mock_target STATIC target_include_directories(mock_target PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/mock - ${SCHEMA_BUILD_DIR} ) target_compile_options(mock_target PUBLIC ${TEST_COMPILE_FLAGS} ${BUILD_COMPILE_FLAGS}) target_link_options(mock_target PUBLIC ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS}) target_link_libraries(mock_target PUBLIC - flatbuffers_header_only Taskflow + mock_schema mock_toolchain CppUTest @@ -36,5 +35,3 @@ if (${MINGW}) message(WARNING "-Wl,--allow-multiple-definition for MINGW") target_link_options(mock_target PUBLIC -Wl,--allow-multiple-definition) endif() - -add_dependencies(mock_target fbs_to_header) diff --git a/buildcc/lib/target/cmake/target.cmake b/buildcc/lib/target/cmake/target.cmake index c67dd500..fdb0cd8d 100644 --- a/buildcc/lib/target/cmake/target.cmake +++ b/buildcc/lib/target/cmake/target.cmake @@ -16,10 +16,6 @@ if(${BUILDCC_BUILD_AS_SINGLE_LIB}) $ $ ) - target_include_directories(buildcc PRIVATE - ${SCHEMA_BUILD_DIR} - ) - add_dependencies(buildcc fbs_to_header) endif() if(${BUILDCC_BUILD_AS_INTERFACE}) @@ -32,15 +28,10 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) $ ) target_link_libraries(target PUBLIC + schema toolchain - flatbuffers_header_only Taskflow ) - - target_include_directories(target PRIVATE - ${SCHEMA_BUILD_DIR} - ) target_compile_options(target PRIVATE ${BUILD_COMPILE_FLAGS}) target_link_options(target PRIVATE ${BUILD_LINK_FLAGS}) - add_dependencies(target fbs_to_header) endif() diff --git a/buildcc/lib/target/include/target/api/target_getter.h b/buildcc/lib/target/include/target/api/target_getter.h index b9230c81..fc1da53f 100644 --- a/buildcc/lib/target/include/target/api/target_getter.h +++ b/buildcc/lib/target/include/target/api/target_getter.h @@ -20,7 +20,7 @@ #include #include -#include "target/common/target_type.h" +#include "schema/target_type.h" #include "toolchain/toolchain.h" diff --git a/buildcc/lib/target/include/target/api/target_info_getter.h b/buildcc/lib/target/include/target/api/target_info_getter.h index 7c6f191c..bf912122 100644 --- a/buildcc/lib/target/include/target/api/target_info_getter.h +++ b/buildcc/lib/target/include/target/api/target_info_getter.h @@ -17,7 +17,7 @@ #ifndef TARGET_API_TARGET_INFO_GETTER_H_ #define TARGET_API_TARGET_INFO_GETTER_H_ -#include "target/common/path.h" +#include "schema/path.h" #include "target/common/target_config.h" #include "target/common/target_state.h" diff --git a/buildcc/lib/target/include/target/common/util.h b/buildcc/lib/target/include/target/common/util.h index c95f7daa..683216ad 100644 --- a/buildcc/lib/target/include/target/common/util.h +++ b/buildcc/lib/target/include/target/common/util.h @@ -20,7 +20,7 @@ #include #include -#include "target/common/path.h" +#include "schema/path.h" namespace buildcc::internal { diff --git a/buildcc/lib/target/include/target/friend/compile_object.h b/buildcc/lib/target/include/target/friend/compile_object.h index f99c154e..1cbfbc9f 100644 --- a/buildcc/lib/target/include/target/friend/compile_object.h +++ b/buildcc/lib/target/include/target/friend/compile_object.h @@ -19,7 +19,7 @@ #include -#include "target/common/path.h" +#include "schema/path.h" #include "taskflow/core/task.hpp" #include "taskflow/taskflow.hpp" diff --git a/buildcc/lib/target/include/target/generator.h b/buildcc/lib/target/include/target/generator.h index 2e8b22f2..fe013450 100644 --- a/buildcc/lib/target/include/target/generator.h +++ b/buildcc/lib/target/include/target/generator.h @@ -32,9 +32,9 @@ #include "target/interface/builder_interface.h" -#include "target/serialization/generator_serialization.h" +#include "schema/generator_serialization.h" +#include "schema/path.h" -#include "target/common/path.h" #include "target/common/target_env.h" namespace buildcc { diff --git a/buildcc/lib/target/include/target/interface/builder_interface.h b/buildcc/lib/target/include/target/interface/builder_interface.h index cf2b7be8..ae044274 100644 --- a/buildcc/lib/target/include/target/interface/builder_interface.h +++ b/buildcc/lib/target/include/target/interface/builder_interface.h @@ -23,7 +23,6 @@ #include "env/assert_fatal.h" -#include "target/common/path.h" #include "target/common/util.h" namespace buildcc::internal { diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index f70ed25b..4a75c230 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -35,7 +35,7 @@ #include "target/target_info.h" // Common -#include "target/common/target_type.h" +#include "schema/target_type.h" // Friend #include "target/friend/compile_object.h" @@ -43,8 +43,8 @@ #include "target/friend/link_target.h" // Internal -#include "target/common/path.h" -#include "target/serialization/target_serialization.h" +#include "schema/path.h" +#include "schema/target_serialization.h" // Env #include "env/env.h" diff --git a/buildcc/lib/target/include/target/target_info.h b/buildcc/lib/target/include/target/target_info.h index 4250e85c..aa3c22ca 100644 --- a/buildcc/lib/target/include/target/target_info.h +++ b/buildcc/lib/target/include/target/target_info.h @@ -32,7 +32,7 @@ #include "target/api/sync_api.h" #include "target/api/target_info_getter.h" -#include "target/serialization/target_serialization.h" +#include "schema/target_serialization.h" namespace buildcc { diff --git a/buildcc/lib/target/src/common/target_config.cpp b/buildcc/lib/target/src/common/target_config.cpp index 2b67f290..3f7b5135 100644 --- a/buildcc/lib/target/src/common/target_config.cpp +++ b/buildcc/lib/target/src/common/target_config.cpp @@ -18,7 +18,7 @@ #include "env/assert_fatal.h" -#include "target/common/path.h" +#include "schema/path.h" #include "fmt/format.h" diff --git a/buildcc/lib/target/src/target/friend/compile_pch.cpp b/buildcc/lib/target/src/target/friend/compile_pch.cpp index 115138ab..971f36f1 100644 --- a/buildcc/lib/target/src/target/friend/compile_pch.cpp +++ b/buildcc/lib/target/src/target/friend/compile_pch.cpp @@ -16,7 +16,7 @@ #include "target/friend/compile_pch.h" -#include "target/common/path.h" +#include "schema/path.h" #include "target/target.h" #include "env/util.h" diff --git a/buildcc/lib/target/test/path/CMakeLists.txt b/buildcc/lib/target/test/path/CMakeLists.txt index 1b5103ce..c6c9de0f 100644 --- a/buildcc/lib/target/test/path/CMakeLists.txt +++ b/buildcc/lib/target/test/path/CMakeLists.txt @@ -10,7 +10,9 @@ target_include_directories(${TEST_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated ) target_link_libraries(${TEST_NAME} PRIVATE - mock_env + mock_env + mock_schema + CppUTest CppUTestExt gcov diff --git a/buildcc/lib/target/test/path/test_path.cpp b/buildcc/lib/target/test/path/test_path.cpp index dff2ec52..19337a30 100644 --- a/buildcc/lib/target/test/path/test_path.cpp +++ b/buildcc/lib/target/test/path/test_path.cpp @@ -1,5 +1,5 @@ // Internal -#include "target/common/path.h" +#include "schema/path.h" #include "env/assert_fatal.h" diff --git a/buildcc/lib/target/test/target/test_builder_interface.cpp b/buildcc/lib/target/test/target/test_builder_interface.cpp index 84c14749..9cc2d2ac 100644 --- a/buildcc/lib/target/test/target/test_builder_interface.cpp +++ b/buildcc/lib/target/test/target/test_builder_interface.cpp @@ -1,6 +1,6 @@ #include "target/interface/builder_interface.h" -#include "target/common/path.h" +#include "schema/path.h" // NOTE, Make sure all these includes are AFTER the system and header includes #include "CppUTest/CommandLineTestRunner.h" diff --git a/buildcc/lib/target/test/target/test_serialization_interface.cpp b/buildcc/lib/target/test/target/test_serialization_interface.cpp index b5083059..e95db8d1 100644 --- a/buildcc/lib/target/test/target/test_serialization_interface.cpp +++ b/buildcc/lib/target/test/target/test_serialization_interface.cpp @@ -1,4 +1,4 @@ -#include "target/interface/serialization_interface.h" +#include "schema/interface/serialization_interface.h" // NOTE, Make sure all these includes are AFTER the system and header includes #include "CppUTest/CommandLineTestRunner.h" diff --git a/buildcc/lib/target/test/target/test_target_external_lib.cpp b/buildcc/lib/target/test/target/test_target_external_lib.cpp index 72e7dcdf..b081982d 100644 --- a/buildcc/lib/target/test/target/test_target_external_lib.cpp +++ b/buildcc/lib/target/test/target/test_target_external_lib.cpp @@ -7,7 +7,7 @@ #include "target/target.h" -#include "target/serialization/target_serialization.h" +#include "schema/target_serialization.h" #include #include diff --git a/buildcc/lib/target/test/target/test_target_flags.cpp b/buildcc/lib/target/test/target/test_target_flags.cpp index 21acef59..087dab6f 100644 --- a/buildcc/lib/target/test/target/test_target_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_flags.cpp @@ -8,7 +8,7 @@ #include "env/env.h" // -#include "target/serialization/target_serialization.h" +#include "schema/target_serialization.h" // Third Party diff --git a/buildcc/lib/target/test/target/test_target_lib_dep.cpp b/buildcc/lib/target/test/target/test_target_lib_dep.cpp index f9ff8faf..5fc80122 100644 --- a/buildcc/lib/target/test/target/test_target_lib_dep.cpp +++ b/buildcc/lib/target/test/target/test_target_lib_dep.cpp @@ -9,7 +9,7 @@ #include "target/target.h" // -#include "target/serialization/target_serialization.h" +#include "schema/target_serialization.h" #include #include diff --git a/buildcc/plugins/src/buildcc_find.cpp b/buildcc/plugins/src/buildcc_find.cpp index 94e6aac9..97a6e1c1 100644 --- a/buildcc/plugins/src/buildcc_find.cpp +++ b/buildcc/plugins/src/buildcc_find.cpp @@ -23,7 +23,7 @@ #include "env/host_os_util.h" #include "env/logging.h" -#include "target/common/path.h" +#include "schema/path.h" namespace { constexpr const char *const kEnvVarNotFound = diff --git a/buildcc/schema/CMakeLists.txt b/buildcc/schema/CMakeLists.txt index cbbe4b23..6883e1a5 100644 --- a/buildcc/schema/CMakeLists.txt +++ b/buildcc/schema/CMakeLists.txt @@ -1,26 +1,2 @@ -# Generate files -set(SCHEMA_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated CACHE PATH "Generate path of flatbuffer schema") - -set(FBS_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/path.fbs - ${CMAKE_CURRENT_SOURCE_DIR}/generator.fbs - ${CMAKE_CURRENT_SOURCE_DIR}/target.fbs -) -set(FBS_GEN_FILES - ${SCHEMA_BUILD_DIR}/path_generated.h - ${SCHEMA_BUILD_DIR}/generator_generated.h - ${SCHEMA_BUILD_DIR}/target_generated.h -) -set(FBS_GEN_OPTIONS - -I ${CMAKE_CURRENT_SOURCE_DIR} - --gen-object-api -) - -add_custom_command(OUTPUT ${FBS_GEN_FILES} - COMMAND flatc -o ${SCHEMA_BUILD_DIR} ${FBS_GEN_OPTIONS} --cpp ${FBS_FILES} - DEPENDS flatc ${FBS_FILES} -) - -add_custom_target(fbs_to_header - DEPENDS ${FBS_GEN_FILES} -) +include(cmake/schema_generate.cmake) +include(cmake/schema.cmake) diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake new file mode 100644 index 00000000..99d9949c --- /dev/null +++ b/buildcc/schema/cmake/schema.cmake @@ -0,0 +1,89 @@ +# schema test +if (${TESTING}) + add_library(mock_schema STATIC + src/generator_serialization.cpp + src/target_serialization.cpp + + include/schema/private/schema_util.h + include/schema/interface/serialization_interface.h + + include/schema/path.h + include/schema/generator_serialization.h + include/schema/target_serialization.h + ) + target_include_directories(mock_schema PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/mock/include + ${SCHEMA_BUILD_DIR} + ) + target_link_libraries(mock_schema PUBLIC + mock_env + flatbuffers_header_only + + CppUTest + CppUTestExt + gcov + ) + add_dependencies(mock_schema fbs_to_header) + + target_compile_options(mock_schema PUBLIC ${TEST_COMPILE_FLAGS} ${BUILD_COMPILE_FLAGS}) + target_link_options(mock_schema PUBLIC ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS}) + + # Tests + add_dependencies(mock_schema fbs_to_header) +endif() + +set(SCHEMA_SRCS + src/generator_serialization.cpp + src/target_serialization.cpp + + include/schema/private/schema_util.h + include/schema/interface/serialization_interface.h + + include/schema/path.h + include/schema/generator_serialization.h + include/schema/target_serialization.h +) + +if(${BUILDCC_BUILD_AS_SINGLE_LIB}) + target_sources(buildcc PRIVATE + ${SCHEMA_SRCS} + ) + target_include_directories(buildcc PUBLIC + $ + $ + ) + target_include_directories(buildcc PRIVATE + ${SCHEMA_BUILD_DIR} + ) + add_dependencies(buildcc fbs_to_header) +endif() + +if(${BUILDCC_BUILD_AS_INTERFACE}) + m_clangtidy("schema") + add_library(schema + ${SCHEMA_SRCS} + ) + target_include_directories(schema PUBLIC + $ + $ + ) + target_include_directories(schema PRIVATE + ${SCHEMA_BUILD_DIR} + ) + target_compile_options(schema PRIVATE ${BUILD_COMPILE_FLAGS}) + target_link_options(schema PRIVATE ${BUILD_LINK_FLAGS}) + target_link_libraries(schema PRIVATE + flatbuffers_header_only + env + ) + add_dependencies(schema fbs_to_header) +endif() + +if (${BUILDCC_INSTALL}) + if (${BUILDCC_BUILD_AS_INTERFACE}) + install(TARGETS schema DESTINATION lib EXPORT schemaConfig) + install(EXPORT schemaConfig DESTINATION "${BUILDCC_INSTALL_LIB_PREFIX}/schema") + endif() + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION "${BUILDCC_INSTALL_HEADER_PREFIX}") +endif() diff --git a/buildcc/schema/cmake/schema_generate.cmake b/buildcc/schema/cmake/schema_generate.cmake new file mode 100644 index 00000000..cbbe4b23 --- /dev/null +++ b/buildcc/schema/cmake/schema_generate.cmake @@ -0,0 +1,26 @@ +# Generate files +set(SCHEMA_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated CACHE PATH "Generate path of flatbuffer schema") + +set(FBS_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/path.fbs + ${CMAKE_CURRENT_SOURCE_DIR}/generator.fbs + ${CMAKE_CURRENT_SOURCE_DIR}/target.fbs +) +set(FBS_GEN_FILES + ${SCHEMA_BUILD_DIR}/path_generated.h + ${SCHEMA_BUILD_DIR}/generator_generated.h + ${SCHEMA_BUILD_DIR}/target_generated.h +) +set(FBS_GEN_OPTIONS + -I ${CMAKE_CURRENT_SOURCE_DIR} + --gen-object-api +) + +add_custom_command(OUTPUT ${FBS_GEN_FILES} + COMMAND flatc -o ${SCHEMA_BUILD_DIR} ${FBS_GEN_OPTIONS} --cpp ${FBS_FILES} + DEPENDS flatc ${FBS_FILES} +) + +add_custom_target(fbs_to_header + DEPENDS ${FBS_GEN_FILES} +) diff --git a/buildcc/lib/target/include/target/serialization/generator_serialization.h b/buildcc/schema/include/schema/generator_serialization.h similarity index 88% rename from buildcc/lib/target/include/target/serialization/generator_serialization.h rename to buildcc/schema/include/schema/generator_serialization.h index dfe9553f..9ee77298 100644 --- a/buildcc/lib/target/include/target/serialization/generator_serialization.h +++ b/buildcc/schema/include/schema/generator_serialization.h @@ -14,16 +14,16 @@ * limitations under the License. */ -#ifndef TARGET_SERIALIZATION_GENERATOR_SERIALIZATION_H_ -#define TARGET_SERIALIZATION_GENERATOR_SERIALIZATION_H_ - -#include "target/interface/serialization_interface.h" +#ifndef SCHEMA_GENERATOR_SERIALIZATION_H_ +#define SCHEMA_GENERATOR_SERIALIZATION_H_ #include #include #include -#include "target/common/path.h" +#include "schema/path.h" + +#include "schema/interface/serialization_interface.h" namespace buildcc::internal { diff --git a/buildcc/lib/target/include/target/interface/serialization_interface.h b/buildcc/schema/include/schema/interface/serialization_interface.h similarity index 93% rename from buildcc/lib/target/include/target/interface/serialization_interface.h rename to buildcc/schema/include/schema/interface/serialization_interface.h index 2e2ca654..df30f978 100644 --- a/buildcc/lib/target/include/target/interface/serialization_interface.h +++ b/buildcc/schema/include/schema/interface/serialization_interface.h @@ -14,15 +14,15 @@ * limitations under the License. */ -#ifndef TARGET_INTERFACE_SERIALIZATION_INTERFACE_H_ -#define TARGET_INTERFACE_SERIALIZATION_INTERFACE_H_ +#ifndef SCHEMA_INTERFACE_SERIALIZATION_INTERFACE_H_ +#define SCHEMA_INTERFACE_SERIALIZATION_INTERFACE_H_ #include #include "env/assert_fatal.h" #include "env/util.h" -#include "target/common/path.h" +#include "schema/path.h" namespace fs = std::filesystem; diff --git a/buildcc/lib/target/include/target/common/path.h b/buildcc/schema/include/schema/path.h similarity index 98% rename from buildcc/lib/target/include/target/common/path.h rename to buildcc/schema/include/schema/path.h index ad4314f1..2ee2f3ae 100644 --- a/buildcc/lib/target/include/target/common/path.h +++ b/buildcc/schema/include/schema/path.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef TARGET_COMMON_PATH_H_ -#define TARGET_COMMON_PATH_H_ +#ifndef SCHEMA_PATH_H_ +#define SCHEMA_PATH_H_ #include #include diff --git a/buildcc/lib/target/include/target/private/schema_util.h b/buildcc/schema/include/schema/private/schema_util.h similarity index 97% rename from buildcc/lib/target/include/target/private/schema_util.h rename to buildcc/schema/include/schema/private/schema_util.h index b0ad689b..2684c2f5 100644 --- a/buildcc/lib/target/include/target/private/schema_util.h +++ b/buildcc/schema/include/schema/private/schema_util.h @@ -14,14 +14,14 @@ * limitations under the License. */ -#ifndef TARGET_PRIVATE_SCHEMA_UTIL_H_ -#define TARGET_PRIVATE_SCHEMA_UTIL_H_ +#ifndef SCHEMA_PRIVATE_SCHEMA_UTIL_H_ +#define SCHEMA_PRIVATE_SCHEMA_UTIL_H_ #include "path_generated.h" #include -#include "target/common/path.h" +#include "schema/path.h" namespace fbs = schema::internal; diff --git a/buildcc/lib/target/include/target/serialization/target_serialization.h b/buildcc/schema/include/schema/target_serialization.h similarity index 91% rename from buildcc/lib/target/include/target/serialization/target_serialization.h rename to buildcc/schema/include/schema/target_serialization.h index c8e6b882..84914ffb 100644 --- a/buildcc/lib/target/include/target/serialization/target_serialization.h +++ b/buildcc/schema/include/schema/target_serialization.h @@ -14,15 +14,15 @@ * limitations under the License. */ -#ifndef TARGET_SERIALIZATION_TARGET_SERIALIZATION_H_ -#define TARGET_SERIALIZATION_TARGET_SERIALIZATION_H_ - -#include "target/interface/serialization_interface.h" +#ifndef SCHEMA_TARGET_SERIALIZATION_H_ +#define SCHEMA_TARGET_SERIALIZATION_H_ #include -#include "target/common/path.h" -#include "target/common/target_type.h" +#include "schema/path.h" +#include "schema/target_type.h" + +#include "schema/interface/serialization_interface.h" namespace buildcc::internal { diff --git a/buildcc/lib/target/include/target/common/target_type.h b/buildcc/schema/include/schema/target_type.h similarity index 91% rename from buildcc/lib/target/include/target/common/target_type.h rename to buildcc/schema/include/schema/target_type.h index ff8d05a1..eb4632ab 100644 --- a/buildcc/lib/target/include/target/common/target_type.h +++ b/buildcc/schema/include/schema/target_type.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef TARGET_COMMON_TARGET_TYPE_H_ -#define TARGET_COMMON_TARGET_TYPE_H_ +#ifndef SCHEMA_TARGET_TYPE_H_ +#define SCHEMA_TARGET_TYPE_H_ namespace buildcc { diff --git a/buildcc/lib/target/src/generator/generator_serialization.cpp b/buildcc/schema/src/generator_serialization.cpp similarity index 95% rename from buildcc/lib/target/src/generator/generator_serialization.cpp rename to buildcc/schema/src/generator_serialization.cpp index 855aae04..cb4370f0 100644 --- a/buildcc/lib/target/src/generator/generator_serialization.cpp +++ b/buildcc/schema/src/generator_serialization.cpp @@ -14,13 +14,13 @@ * limitations under the License. */ -#include "target/serialization/generator_serialization.h" +#include "schema/generator_serialization.h" // Third party #include "flatbuffers/flatbuffers.h" // Private -#include "target/private/schema_util.h" +#include "schema/private/schema_util.h" // Schema generated #include "generator_generated.h" diff --git a/buildcc/lib/target/src/target/target_serialization.cpp b/buildcc/schema/src/target_serialization.cpp similarity index 98% rename from buildcc/lib/target/src/target/target_serialization.cpp rename to buildcc/schema/src/target_serialization.cpp index b965ae56..68fdaa24 100644 --- a/buildcc/lib/target/src/target/target_serialization.cpp +++ b/buildcc/schema/src/target_serialization.cpp @@ -14,13 +14,13 @@ * limitations under the License. */ -#include "target/serialization/target_serialization.h" +#include "schema/target_serialization.h" // Third party #include "flatbuffers/flatbuffers.h" // Private -#include "target/private/schema_util.h" +#include "schema/private/schema_util.h" // Schema generated #include "target_generated.h" diff --git a/doc/software_architecture/buildcc_interface_lib.PNG b/doc/software_architecture/buildcc_interface_lib.PNG index e2cc97aa04b1594407fb6a03014c1cd64d6e25a3..729c9b080b8edeb307aeaa3a663ba9fd05c8df6a 100644 GIT binary patch literal 142148 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 g{OAAwk?+S&TUj~tbL}qK^5-W{G&Mf{OV diff --git a/doc/software_architecture/buildcc_single_lib.PNG b/doc/software_architecture/buildcc_single_lib.PNG index 50e6f27bb02f13de0dc6ebdd9f7d0cc9da294ba4..62c4c929b92acd7528a480f0070263c40cb997c1 100644 GIT binary patch literal 132243 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�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

Hw`8snW(QKwspxobi0J)cqE$ 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 NAtTL>m`+*s{{Vsn!9oB4 diff --git a/docs/source/arch/project_layout.rst b/docs/source/arch/project_layout.rst index b009c523..8fe5298e 100644 --- a/docs/source/arch/project_layout.rst +++ b/docs/source/arch/project_layout.rst @@ -14,11 +14,15 @@ Project Layout ** README.md ** TODO.md * buildcc - ** env - ** toolchain - ** target - ** args - ** register + ** lib + *** env + *** toolchain + *** target + *** args + *** register + ** schema + ** toolchains + ** targets * bootstrap * buildexe * cmake diff --git a/docs/source/arch/software_heirarchy.rst b/docs/source/arch/software_heirarchy.rst index 76538f31..5dfa8e9f 100644 --- a/docs/source/arch/software_heirarchy.rst +++ b/docs/source/arch/software_heirarchy.rst @@ -47,6 +47,7 @@ BuildCC interface lib rectangle "tiny-process-library" as tpl #palegreen rectangle Environment as env #aliceblue + rectangle Schema as schema #aliceblue rectangle Toolchain as toolchain #aliceblue rectangle Target as target #aliceblue rectangle "Toolchain specialized" as toolchain_specialized #aliceblue @@ -61,17 +62,19 @@ BuildCC interface lib spdlog .up.> env tpl .up.> env - flatbuffers .up.> target - taskflow -up-> target - cli11 -up-> args taskflow -up-> register + flatbuffers .up.> schema + env -up-> toolchain + env -up-> schema + taskflow -up-> target + schema -up-> target toolchain -up-> target - toolchain -up-> toolchain_specialized + toolchain -up-> toolchain_specialized target -up-> target_specialized target -up-> args From c9c2cd8c3a36a334bdde2214c68444018063ead1 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 20 Feb 2022 21:52:40 -0800 Subject: [PATCH 03/35] Toolchain config (#194) Instead of having all configurations on the Target level, we have common parameters on the Toolchain level (which can be used by the corresponding targets). - TargetInfo now requires Toolchain - Some TargetConfig parameters are shifted to ToolchainConfig --- .github/workflows/msvc-analysis.yml | 2 +- bootstrap/src/build_buildcc.cpp | 18 ++-- .../lib/target/cmake/common_target_src.cmake | 1 - buildcc/lib/target/cmake/mock_target.cmake | 1 - buildcc/lib/target/cmake/target.cmake | 1 - .../include/target/common/target_config.h | 66 ------------ .../include/target/common/target_state.h | 4 +- buildcc/lib/target/include/target/target.h | 10 +- .../lib/target/include/target/target_info.h | 8 +- buildcc/lib/target/src/api/include_api.cpp | 4 +- buildcc/lib/target/src/api/pch_api.cpp | 2 +- buildcc/lib/target/src/api/source_api.cpp | 6 +- .../lib/target/src/common/target_config.cpp | 65 +---------- .../lib/target/src/common/target_state.cpp | 12 +-- buildcc/lib/target/src/target/build.cpp | 11 +- .../src/target/friend/compile_object.cpp | 5 +- .../target/src/target/friend/compile_pch.cpp | 15 +-- .../target/src/target/friend/link_target.cpp | 2 +- buildcc/lib/target/src/target/target.cpp | 16 +-- buildcc/lib/target/test/target/CMakeLists.txt | 6 -- .../target/test/target/test_target_config.cpp | 41 ------- .../target/test/target/test_target_state.cpp | 12 +-- buildcc/lib/toolchain/CMakeLists.txt | 18 +++- .../include/toolchain/common/file_ext.h} | 6 +- .../toolchain/common/toolchain_config.h | 101 ++++++++++++++++++ .../toolchain/include/toolchain/toolchain.h | 18 +++- .../toolchain/src/common/toolchain_config.cpp | 88 +++++++++++++++ .../toolchain/test/test_toolchain_config.cpp | 41 +++++++ buildcc/schema/cmake/schema.cmake | 4 +- buildcc/targets/include/targets/target_gcc.h | 13 --- .../targets/include/targets/target_mingw.h | 5 - buildcc/targets/include/targets/target_msvc.h | 12 --- .../include/toolchains/toolchain_gcc.h | 15 +++ .../include/toolchains/toolchain_mingw.h | 15 +++ .../include/toolchains/toolchain_msvc.h | 16 +++ buildexe/src/build_env_setup.cpp | 26 +---- .../buildcc_interface_lib.PNG | Bin 142148 -> 144370 bytes docs/source/arch/software_heirarchy.rst | 7 +- docs/source/user_api/target_utils.rst | 5 - docs/source/user_api/toc.rst | 1 + docs/source/user_api/toolchain_utils.rst | 14 +++ example/hybrid/target_info/build.cpp | 20 ++-- 42 files changed, 420 insertions(+), 313 deletions(-) delete mode 100644 buildcc/lib/target/test/target/test_target_config.cpp rename buildcc/lib/{target/include/target/common/target_file_ext.h => toolchain/include/toolchain/common/file_ext.h} (88%) create mode 100644 buildcc/lib/toolchain/include/toolchain/common/toolchain_config.h create mode 100644 buildcc/lib/toolchain/src/common/toolchain_config.cpp create mode 100644 buildcc/lib/toolchain/test/test_toolchain_config.cpp create mode 100644 docs/source/user_api/toolchain_utils.rst diff --git a/.github/workflows/msvc-analysis.yml b/.github/workflows/msvc-analysis.yml index a2628f34..bd370187 100644 --- a/.github/workflows/msvc-analysis.yml +++ b/.github/workflows/msvc-analysis.yml @@ -25,7 +25,7 @@ env: jobs: analyze: name: Analyze - runs-on: windows-latest + runs-on: windows-2019 steps: - name: Checkout repository diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index 33b1066b..70765e9d 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -62,9 +62,11 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, // TOOLCHAIN target.GlobSources("lib/toolchain/src/api"); + target.GlobSources("lib/toolchain/src/common"); target.AddIncludeDir("lib/toolchain/include"); target.GlobHeaders("lib/toolchain/include/toolchain"); target.GlobHeaders("lib/toolchain/include/toolchain/api"); + target.GlobHeaders("lib/toolchain/include/toolchain/common"); // TARGET target.GlobSources("lib/target/src/common"); @@ -205,33 +207,35 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { // Flatbuffers HO lib auto &flatbuffers_ho_lib = storage_.Add( - kFlatbuffersHoName, + kFlatbuffersHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "flatbuffers", env_.GetTargetBuildDir())); reg_.CallbackIf(state, flatbuffers_ho_cb, flatbuffers_ho_lib); // CLI11 HO lib auto &cli11_ho_lib = storage_.Add( - kCli11HoName, TargetEnv(env_.GetTargetRootDir() / "third_party" / "CLI11", - env_.GetTargetBuildDir())); + kCli11HoName, toolchain_, + TargetEnv(env_.GetTargetRootDir() / "third_party" / "CLI11", + env_.GetTargetBuildDir())); reg_.CallbackIf(state, cli11_ho_cb, cli11_ho_lib); // fmt HO lib auto &fmt_ho_lib = storage_.Add( - kFmtHoName, TargetEnv(env_.GetTargetRootDir() / "third_party" / "fmt", - env_.GetTargetBuildDir())); + kFmtHoName, toolchain_, + TargetEnv(env_.GetTargetRootDir() / "third_party" / "fmt", + env_.GetTargetBuildDir())); reg_.CallbackIf(state, fmt_ho_cb, fmt_ho_lib); // spdlog HO lib auto &spdlog_ho_lib = storage_.Add( - kSpdlogHoName, + kSpdlogHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "spdlog", env_.GetTargetBuildDir())); reg_.CallbackIf(state, spdlog_ho_cb, spdlog_ho_lib); // taskflow HO lib auto &taskflow_ho_lib = storage_.Add( - kTaskflowHoName, + kTaskflowHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "taskflow", env_.GetTargetBuildDir())); reg_.CallbackIf(state, taskflow_ho_cb, taskflow_ho_lib); diff --git a/buildcc/lib/target/cmake/common_target_src.cmake b/buildcc/lib/target/cmake/common_target_src.cmake index 875e5edf..6f2bb771 100644 --- a/buildcc/lib/target/cmake/common_target_src.cmake +++ b/buildcc/lib/target/cmake/common_target_src.cmake @@ -7,7 +7,6 @@ set(COMMON_TARGET_SRCS src/common/target_state.cpp include/target/common/target_config.h include/target/common/target_state.h - include/target/common/target_file_ext.h include/target/common/target_env.h src/common/util.cpp diff --git a/buildcc/lib/target/cmake/mock_target.cmake b/buildcc/lib/target/cmake/mock_target.cmake index da18b626..39ec8a77 100644 --- a/buildcc/lib/target/cmake/mock_target.cmake +++ b/buildcc/lib/target/cmake/mock_target.cmake @@ -21,7 +21,6 @@ target_link_options(mock_target PUBLIC ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS}) target_link_libraries(mock_target PUBLIC Taskflow - mock_schema mock_toolchain CppUTest diff --git a/buildcc/lib/target/cmake/target.cmake b/buildcc/lib/target/cmake/target.cmake index fdb0cd8d..98f16479 100644 --- a/buildcc/lib/target/cmake/target.cmake +++ b/buildcc/lib/target/cmake/target.cmake @@ -28,7 +28,6 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) $ ) target_link_libraries(target PUBLIC - schema toolchain Taskflow ) diff --git a/buildcc/lib/target/include/target/common/target_config.h b/buildcc/lib/target/include/target/common/target_config.h index 172c52b0..a09d2595 100644 --- a/buildcc/lib/target/include/target/common/target_config.h +++ b/buildcc/lib/target/include/target/common/target_config.h @@ -21,8 +21,6 @@ #include #include -#include "target/common/target_file_ext.h" - namespace fs = std::filesystem; namespace buildcc { @@ -30,77 +28,13 @@ namespace buildcc { struct TargetConfig { TargetConfig() = default; - /** - * @brief Get the valid file extension from a path - * - * See TargetConfig::valid_c_ext, TargetConfig::valid_cpp_ext, - * TargetConfig::valid_asm_ext, TargetConfig::valid_header_ext - * - * @param filepath Absolute / Relative path of the file - * @return TargetFileExt File path detected as per TargetConfig::valid_* - * variables - */ - TargetFileExt GetFileExt(const fs::path &filepath) const; - - /** - * @brief Checks for C/C++ source file validity. - * - * See TargetConfig::valid_c_ext, TargetConfig::valid_cpp_ext, - * TargetConfig::valid_asm_ext - * - * @param filepath Absolute / Relative path of file - * @return true If file extension belongs to the above valid_* list - * @return false If file extension does not belong to the above valid_* list - */ - bool IsValidSource(const fs::path &filepath) const; - - /** - * @brief Checks for Header file validity - * - * See TargetConfig::valid_header_ext - * - * @param filepath Absolute / Relative path of file - * @return true If file extension belongs to above valid_* list - * @return false If file extension does not belong to above valid_* list - */ - bool IsValidHeader(const fs::path &filepath) const; - - /** - * @brief Expects Source file validity - * - * env::assert_fatal if not a valid source - * - * @param filepath Absolute / Relative path of file - */ - void ExpectsValidSource(const fs::path &filepath) const; - - /** - * @brief Expects header file validity - * - * env::assert_fatal if not a valid header - * - * @param filepath Absolute / Relative path of file - */ - void ExpectsValidHeader(const fs::path &filepath) const; - std::string target_ext{""}; - std::string obj_ext{".o"}; - std::string pch_header_ext{".h"}; - std::string pch_compile_ext{".gch"}; - - std::string prefix_include_dir{"-I"}; - std::string prefix_lib_dir{"-L"}; // clang-format off std::string pch_command{"{compiler} {preprocessor_flags} {include_dirs} {common_compile_flags} {pch_compile_flags} {compile_flags} -o {output} -c {input}"}; std::string compile_command{"{compiler} {preprocessor_flags} {include_dirs} {common_compile_flags} {pch_object_flags} {compile_flags} -o {output} -c {input}"}; std::string link_command{"{cpp_compiler} {link_flags} {compiled_sources} -o {output} {lib_dirs} {lib_deps}"}; // clang-format on - - std::unordered_set valid_c_ext{".c"}; - std::unordered_set valid_cpp_ext{".cpp", ".cxx", ".cc"}; - std::unordered_set valid_asm_ext{".s", ".S", ".asm"}; - std::unordered_set valid_header_ext{".h", ".hpp"}; }; } // namespace buildcc diff --git a/buildcc/lib/target/include/target/common/target_state.h b/buildcc/lib/target/include/target/common/target_state.h index cc7e06eb..3afc766f 100644 --- a/buildcc/lib/target/include/target/common/target_state.h +++ b/buildcc/lib/target/include/target/common/target_state.h @@ -17,7 +17,7 @@ #ifndef TARGET_COMMON_TARGET_STATE_H_ #define TARGET_COMMON_TARGET_STATE_H_ -#include "target/common/target_file_ext.h" +#include "toolchain/common/file_ext.h" namespace buildcc { @@ -27,7 +27,7 @@ namespace buildcc { // TargetInfo does not have a `Build` method, it is only meant to hold // information struct TargetState { - void SetSourceState(TargetFileExt file_extension); + void SetSourceState(FileExt file_extension); void SetPch(); void SetLock(); diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index 4a75c230..a9540a14 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -70,10 +70,12 @@ class Target : public internal::BuilderInterface, const Toolchain &toolchain, const TargetEnv &env, const TargetConfig &config = TargetConfig()) : TargetInfo( + toolchain, TargetEnv(env.GetTargetRootDir(), env.GetTargetBuildDir() / toolchain.GetName() / name), config), - name_(name), type_(type), toolchain_(toolchain), + name_(name), type_(type), + // toolchain_(toolchain), // loader_(name, env_.GetTargetBuildDir()), serialization_(env_.GetTargetBuildDir() / fmt::format("{}.bin", name)), compile_pch_(*this), compile_object_(*this), link_target_(*this) { @@ -99,8 +101,8 @@ class Target : public internal::BuilderInterface, void Initialize(); // - std::optional SelectCompileFlags(TargetFileExt ext) const; - std::optional SelectCompiler(TargetFileExt ext) const; + std::optional SelectCompileFlags(FileExt ext) const; + std::optional SelectCompiler(FileExt ext) const; // Recompilation checks void RecheckPaths(const internal::path_unordered_set &previous_path, @@ -139,7 +141,7 @@ class Target : public internal::BuilderInterface, private: std::string name_; TargetType type_; - const Toolchain &toolchain_; + // const Toolchain &toolchain_; internal::TargetSerialization serialization_; // Friend classes diff --git a/buildcc/lib/target/include/target/target_info.h b/buildcc/lib/target/include/target/target_info.h index aa3c22ca..fb795161 100644 --- a/buildcc/lib/target/include/target/target_info.h +++ b/buildcc/lib/target/include/target/target_info.h @@ -19,6 +19,8 @@ #include +#include "toolchain/toolchain.h" + #include "target/common/target_config.h" #include "target/common/target_env.h" #include "target/common/target_state.h" @@ -60,8 +62,9 @@ class TargetInfo : public internal::SourceApi, public internal::SyncApi, public internal::TargetInfoGetter { public: - TargetInfo(const TargetEnv &env, const TargetConfig &config = TargetConfig()) - : env_(env), config_(config) {} + TargetInfo(const BaseToolchain &toolchain, const TargetEnv &env, + const TargetConfig &config = TargetConfig()) + : toolchain_(toolchain), env_(env), config_(config) {} private: // Inputs @@ -79,6 +82,7 @@ class TargetInfo : public internal::SourceApi, friend class internal::TargetInfoGetter; protected: + const BaseToolchain &toolchain_; TargetEnv env_; TargetConfig config_; diff --git a/buildcc/lib/target/src/api/include_api.cpp b/buildcc/lib/target/src/api/include_api.cpp index a1716935..49ca6241 100644 --- a/buildcc/lib/target/src/api/include_api.cpp +++ b/buildcc/lib/target/src/api/include_api.cpp @@ -25,7 +25,7 @@ void IncludeApi::AddHeaderAbsolute(const fs::path &absolute_filepath) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.config_.ExpectsValidHeader(absolute_filepath); + t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); t.user_.headers.insert(absolute_filepath); } @@ -53,7 +53,7 @@ void IncludeApi::GlobHeadersAbsolute(const fs::path &absolute_path) { T &t = static_cast(*this); for (const auto &p : fs::directory_iterator(absolute_path)) { - if (t.config_.IsValidHeader(p.path())) { + if (t.toolchain_.GetConfig().IsValidHeader(p.path())) { AddHeaderAbsolute(p.path()); } } diff --git a/buildcc/lib/target/src/api/pch_api.cpp b/buildcc/lib/target/src/api/pch_api.cpp index 60d3745e..c0695342 100644 --- a/buildcc/lib/target/src/api/pch_api.cpp +++ b/buildcc/lib/target/src/api/pch_api.cpp @@ -25,7 +25,7 @@ void PchApi::AddPchAbsolute(const fs::path &absolute_filepath) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.config_.ExpectsValidHeader(absolute_filepath); + t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); const fs::path absolute_pch = fs::path(absolute_filepath).make_preferred(); t.user_.pchs.insert(absolute_pch); diff --git a/buildcc/lib/target/src/api/source_api.cpp b/buildcc/lib/target/src/api/source_api.cpp index 78d260a9..cc47cda3 100644 --- a/buildcc/lib/target/src/api/source_api.cpp +++ b/buildcc/lib/target/src/api/source_api.cpp @@ -25,7 +25,7 @@ void SourceApi::AddSourceAbsolute(const fs::path &absolute_source) { T &t = static_cast(*this); t.state_.ExpectsUnlock(); - t.config_.ExpectsValidSource(absolute_source); + t.toolchain_.GetConfig().ExpectsValidSource(absolute_source); t.user_.sources.emplace(fs::path(absolute_source).make_preferred()); } @@ -34,7 +34,7 @@ void SourceApi::GlobSourcesAbsolute(const fs::path &absolute_source_dir) { T &t = static_cast(*this); for (const auto &p : fs::directory_iterator(absolute_source_dir)) { - if (t.config_.IsValidSource(p.path())) { + if (t.toolchain_.GetConfig().IsValidSource(p.path())) { AddSourceAbsolute(p.path()); } } @@ -59,7 +59,7 @@ void SourceApi::GlobSources(const fs::path &relative_to_target_path) { fs::path absolute_input_path = t.env_.GetTargetRootDir() / relative_to_target_path; for (const auto &p : fs::directory_iterator(absolute_input_path)) { - if (t.config_.IsValidSource(p.path())) { + if (t.toolchain_.GetConfig().IsValidSource(p.path())) { AddSourceAbsolute(p.path()); } } diff --git a/buildcc/lib/target/src/common/target_config.cpp b/buildcc/lib/target/src/common/target_config.cpp index 3f7b5135..23207ac1 100644 --- a/buildcc/lib/target/src/common/target_config.cpp +++ b/buildcc/lib/target/src/common/target_config.cpp @@ -22,67 +22,4 @@ #include "fmt/format.h" -namespace buildcc { - -TargetFileExt TargetConfig::GetFileExt(const fs::path &filepath) const { - if (!filepath.has_extension()) { - return TargetFileExt::Invalid; - } - - TargetFileExt type = TargetFileExt::Invalid; - const std::string ext = filepath.extension().string(); - - if (valid_c_ext.count(ext) == 1) { - type = TargetFileExt::C; - } else if (valid_cpp_ext.count(ext) == 1) { - type = TargetFileExt::Cpp; - } else if (valid_asm_ext.count(ext) == 1) { - type = TargetFileExt::Asm; - } else if (valid_header_ext.count(ext) == 1) { - type = TargetFileExt::Header; - } - - return type; -} - -bool TargetConfig::IsValidSource(const fs::path &filepath) const { - if (!filepath.has_extension()) { - return false; - } - - const std::string ext = filepath.extension().string(); - bool valid = false; - if ((valid_c_ext.find(ext) != valid_c_ext.end()) || - (valid_cpp_ext.find(ext) != valid_cpp_ext.end()) || - (valid_asm_ext.find(ext) != valid_asm_ext.end())) { - valid = true; - } - return valid; -} - -void TargetConfig::ExpectsValidSource(const fs::path &filepath) const { - env::assert_fatal( - IsValidSource(filepath), - fmt::format("{} does not have a valid source extension", filepath)); -} - -bool TargetConfig::IsValidHeader(const fs::path &filepath) const { - if (!filepath.has_extension()) { - return {}; - } - - const std::string ext = filepath.extension().string(); - bool valid = false; - if ((valid_header_ext.find(ext) != valid_header_ext.end())) { - valid = true; - } - return valid; -} - -void TargetConfig::ExpectsValidHeader(const fs::path &filepath) const { - env::assert_fatal( - IsValidHeader(filepath), - fmt::format("{} does not have a valid header extension", filepath)); -} - -} // namespace buildcc +namespace buildcc {} // namespace buildcc diff --git a/buildcc/lib/target/src/common/target_state.cpp b/buildcc/lib/target/src/common/target_state.cpp index d2740547..95a8a022 100644 --- a/buildcc/lib/target/src/common/target_state.cpp +++ b/buildcc/lib/target/src/common/target_state.cpp @@ -20,19 +20,19 @@ namespace buildcc { -void TargetState::SetSourceState(TargetFileExt file_extension) { +void TargetState::SetSourceState(FileExt file_extension) { switch (file_extension) { - case TargetFileExt::Asm: + case FileExt::Asm: contains_asm = true; break; - case TargetFileExt::C: + case FileExt::C: contains_c = true; break; - case TargetFileExt::Cpp: + case FileExt::Cpp: contains_cpp = true; break; - case TargetFileExt::Header: - case TargetFileExt::Invalid: + case FileExt::Header: + case FileExt::Invalid: default: break; } diff --git a/buildcc/lib/target/src/target/build.cpp b/buildcc/lib/target/src/target/build.cpp index 4e9de6c6..7d00cd19 100644 --- a/buildcc/lib/target/src/target/build.cpp +++ b/buildcc/lib/target/src/target/build.cpp @@ -66,7 +66,7 @@ void Target::Build() { // Source state for (const auto &abs_source : user_.sources) { // Set state - state_.SetSourceState(config_.GetFileExt(abs_source)); + state_.SetSourceState(toolchain_.GetConfig().GetFileExt(abs_source)); // Relate input source with output object compile_object_.AddObjectData(abs_source); @@ -74,10 +74,11 @@ void Target::Build() { // Target default arguments command_.AddDefaultArguments({ - {kIncludeDirs, internal::aggregate_with_prefix(config_.prefix_include_dir, - GetIncludeDirs())}, - {kLibDirs, - internal::aggregate_with_prefix(config_.prefix_lib_dir, GetLibDirs())}, + {kIncludeDirs, + internal::aggregate_with_prefix( + toolchain_.GetConfig().prefix_include_dir, GetIncludeDirs())}, + {kLibDirs, internal::aggregate_with_prefix( + toolchain_.GetConfig().prefix_lib_dir, GetLibDirs())}, {kPreprocessorFlags, internal::aggregate(GetPreprocessorFlags())}, {kCommonCompileFlags, internal::aggregate(GetCommonCompileFlags())}, diff --git a/buildcc/lib/target/src/target/friend/compile_object.cpp b/buildcc/lib/target/src/target/friend/compile_object.cpp index 846108df..c9b46bdf 100644 --- a/buildcc/lib/target/src/target/friend/compile_object.cpp +++ b/buildcc/lib/target/src/target/friend/compile_object.cpp @@ -46,7 +46,8 @@ void CompileObject::CacheCompileCommands() { fmt::format("{}", GetObjectData(absolute_current_source).output); const std::string input = fmt::format("{}", absolute_current_source); - const auto type = target_.config_.GetFileExt(absolute_current_source); + const auto type = + target_.toolchain_.GetConfig().GetFileExt(absolute_current_source); const std::string selected_aggregated_compile_flags = target_.SelectCompileFlags(type).value_or(""); const std::string selected_compiler = @@ -156,7 +157,7 @@ CompileObject::ConstructObjectPath(const fs::path &absolute_source_file) const { fs::path absolute_compiled_source = target_.GetTargetBuildDir() / relative; absolute_compiled_source.replace_filename( fmt::format("{}{}", absolute_source_file.filename().string(), - target_.GetConfig().obj_ext)); + target_.toolchain_.GetConfig().obj_ext)); return absolute_compiled_source; } diff --git a/buildcc/lib/target/src/target/friend/compile_pch.cpp b/buildcc/lib/target/src/target/friend/compile_pch.cpp index 971f36f1..312b8b7c 100644 --- a/buildcc/lib/target/src/target/friend/compile_pch.cpp +++ b/buildcc/lib/target/src/target/friend/compile_pch.cpp @@ -117,13 +117,14 @@ void CompilePch::BuildCompile() { fs::path CompilePch::ConstructHeaderPath() const { return target_.GetTargetBuildDir() / - fmt::format("buildcc_pch{}", target_.GetConfig().pch_header_ext); + fmt::format("buildcc_pch{}", + target_.toolchain_.GetConfig().pch_header_ext); } fs::path CompilePch::ConstructCompilePath() const { return ConstructHeaderPath().replace_extension( - fmt::format("{}{}", target_.GetConfig().pch_header_ext, - target_.GetConfig().pch_compile_ext)); + fmt::format("{}{}", target_.toolchain_.GetConfig().pch_header_ext, + target_.toolchain_.GetConfig().pch_compile_ext)); } fs::path CompilePch::ConstructSourcePath(bool has_cpp) const { @@ -133,7 +134,7 @@ fs::path CompilePch::ConstructSourcePath(bool has_cpp) const { fs::path CompilePch::ConstructObjectPath() const { return ConstructHeaderPath().replace_extension( - fmt::format("{}", target_.GetConfig().obj_ext)); + fmt::format("{}", target_.toolchain_.GetConfig().obj_ext)); } std::string CompilePch::ConstructCompileCommand() const { @@ -141,14 +142,14 @@ std::string CompilePch::ConstructCompileCommand() const { ? target_.GetToolchain().GetCppCompiler() : target_.GetToolchain().GetCCompiler(); compiler = fmt::format("{}", fs::path(compiler)); - const TargetFileExt file_ext_type = - target_.GetState().contains_cpp ? TargetFileExt::Cpp : TargetFileExt::C; + const FileExt file_ext_type = + target_.GetState().contains_cpp ? FileExt::Cpp : FileExt::C; const std::string compile_flags = target_.SelectCompileFlags(file_ext_type).value_or(""); const std::string pch_compile_path = fmt::format("{}", compile_path_); const std::string pch_header_path = fmt::format("{}", header_path_); const std::string pch_source_path = fmt::format("{}", source_path_); - return target_.command_.Construct(target_.config_.pch_command, + return target_.command_.Construct(target_.GetConfig().pch_command, { {kCompiler, compiler}, {kCompileFlags, compile_flags}, diff --git a/buildcc/lib/target/src/target/friend/link_target.cpp b/buildcc/lib/target/src/target/friend/link_target.cpp index 2c6fd30e..49bc52b7 100644 --- a/buildcc/lib/target/src/target/friend/link_target.cpp +++ b/buildcc/lib/target/src/target/friend/link_target.cpp @@ -36,7 +36,7 @@ void LinkTarget::CacheLinkCommand() { const std::string output_target = fmt::format("{}", output_); const auto &target_user_schema = target_.user_; command_ = target_.command_.Construct( - target_.config_.link_command, + target_.GetConfig().link_command, { {kOutput, output_target}, {kCompiledSources, aggregated_compiled_sources}, diff --git a/buildcc/lib/target/src/target/target.cpp b/buildcc/lib/target/src/target/target.cpp index 571cd9a4..dd4aedbe 100644 --- a/buildcc/lib/target/src/target/target.cpp +++ b/buildcc/lib/target/src/target/target.cpp @@ -89,15 +89,15 @@ void Target::RecheckExternalLib( std::bind(&Target::ExternalLibChanged, this)); } -std::optional Target::SelectCompileFlags(TargetFileExt ext) const { +std::optional Target::SelectCompileFlags(FileExt ext) const { switch (ext) { - case TargetFileExt::Asm: + case FileExt::Asm: return internal::aggregate(GetAsmCompileFlags()); break; - case TargetFileExt::C: + case FileExt::C: return internal::aggregate(GetCCompileFlags()); break; - case TargetFileExt::Cpp: + case FileExt::Cpp: return internal::aggregate(GetCppCompileFlags()); break; default: @@ -106,15 +106,15 @@ std::optional Target::SelectCompileFlags(TargetFileExt ext) const { return {}; } -std::optional Target::SelectCompiler(TargetFileExt ext) const { +std::optional Target::SelectCompiler(FileExt ext) const { switch (ext) { - case TargetFileExt::Asm: + case FileExt::Asm: return GetToolchain().GetAsmCompiler(); break; - case TargetFileExt::C: + case FileExt::C: return GetToolchain().GetCCompiler(); break; - case TargetFileExt::Cpp: + case FileExt::Cpp: return GetToolchain().GetCppCompiler(); break; default: diff --git a/buildcc/lib/target/test/target/CMakeLists.txt b/buildcc/lib/target/test/target/CMakeLists.txt index 9b914b55..83d29bbe 100644 --- a/buildcc/lib/target/test/target/CMakeLists.txt +++ b/buildcc/lib/target/test/target/CMakeLists.txt @@ -25,17 +25,11 @@ add_test(NAME test_serialization_interface COMMAND test_serialization_interface ) # Common -add_executable(test_target_config - test_target_config.cpp -) -target_link_libraries(test_target_config PRIVATE target_interface) - add_executable(test_target_state test_target_state.cpp ) target_link_libraries(test_target_state PRIVATE target_interface) -add_test(NAME test_target_config COMMAND test_target_config) add_test(NAME test_target_state COMMAND test_target_state) # Generator diff --git a/buildcc/lib/target/test/target/test_target_config.cpp b/buildcc/lib/target/test/target/test_target_config.cpp deleted file mode 100644 index e0fcfcf0..00000000 --- a/buildcc/lib/target/test/target/test_target_config.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "target/common/target_config.h" - -// NOTE, Make sure all these includes are AFTER the system and header includes -#include "CppUTest/CommandLineTestRunner.h" -#include "CppUTest/MemoryLeakDetectorNewMacros.h" -#include "CppUTest/TestHarness.h" -#include "CppUTest/Utest.h" - -// clang-format off -TEST_GROUP(TargetConfigTestGroup) -{ -}; -// clang-format on - -TEST(TargetConfigTestGroup, GetFileExt) { - buildcc::TargetConfig target_config; - - buildcc::TargetFileExt ext; - - ext = target_config.GetFileExt("file.asm"); - CHECK(ext == buildcc::TargetFileExt::Asm); - - ext = target_config.GetFileExt("file.c"); - CHECK(ext == buildcc::TargetFileExt::C); - - ext = target_config.GetFileExt("file.cpp"); - CHECK(ext == buildcc::TargetFileExt::Cpp); - - ext = target_config.GetFileExt("file.h"); - CHECK(ext == buildcc::TargetFileExt::Header); - - ext = target_config.GetFileExt("file.invalid"); - CHECK(ext == buildcc::TargetFileExt::Invalid); - - ext = target_config.GetFileExt("random/directory"); - CHECK(ext == buildcc::TargetFileExt::Invalid); -} - -int main(int ac, char **av) { - return CommandLineTestRunner::RunAllTests(ac, av); -} diff --git a/buildcc/lib/target/test/target/test_target_state.cpp b/buildcc/lib/target/test/target/test_target_state.cpp index 33900732..f3af3363 100644 --- a/buildcc/lib/target/test/target/test_target_state.cpp +++ b/buildcc/lib/target/test/target/test_target_state.cpp @@ -1,5 +1,5 @@ -#include "target/common/target_file_ext.h" #include "target/common/target_state.h" +#include "toolchain/common/file_ext.h" // NOTE, Make sure all these includes are AFTER the system and header includes #include "CppUTest/CommandLineTestRunner.h" @@ -17,20 +17,20 @@ TEST(TargetStateTestGroup, SetSourceState) { buildcc::TargetState target_state; CHECK_FALSE(target_state.contains_c); - target_state.SetSourceState(buildcc::TargetFileExt::C); + target_state.SetSourceState(buildcc::FileExt::C); CHECK_TRUE(target_state.contains_c); CHECK_FALSE(target_state.contains_cpp); - target_state.SetSourceState(buildcc::TargetFileExt::Cpp); + target_state.SetSourceState(buildcc::FileExt::Cpp); CHECK_TRUE(target_state.contains_cpp); CHECK_FALSE(target_state.contains_asm); - target_state.SetSourceState(buildcc::TargetFileExt::Asm); + target_state.SetSourceState(buildcc::FileExt::Asm); CHECK_TRUE(target_state.contains_asm); // Ignored - target_state.SetSourceState(buildcc::TargetFileExt::Header); - target_state.SetSourceState(buildcc::TargetFileExt::Invalid); + target_state.SetSourceState(buildcc::FileExt::Header); + target_state.SetSourceState(buildcc::FileExt::Invalid); } int main(int ac, char **av) { diff --git a/buildcc/lib/toolchain/CMakeLists.txt b/buildcc/lib/toolchain/CMakeLists.txt index edb0cc09..712131ff 100644 --- a/buildcc/lib/toolchain/CMakeLists.txt +++ b/buildcc/lib/toolchain/CMakeLists.txt @@ -1,6 +1,12 @@ set(TOOLCHAIN_SRCS include/toolchain/toolchain.h + include/toolchain/common/file_ext.h + + src/common/toolchain_config.cpp + include/toolchain/common/toolchain_config.h + + # Features src/api/toolchain_verify.cpp include/toolchain/api/toolchain_verify.h ) @@ -14,7 +20,7 @@ if (${TESTING}) target_compile_options(mock_toolchain PUBLIC ${TEST_COMPILE_FLAGS} ${BUILD_COMPILE_FLAGS}) target_link_options(mock_toolchain PUBLIC ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS}) target_link_libraries(mock_toolchain PUBLIC - mock_env + mock_schema CppUTest CppUTestExt @@ -28,9 +34,17 @@ if (${TESTING}) mock_toolchain ) + add_executable(test_toolchain_config + test/test_toolchain_config.cpp + ) + target_link_libraries(test_toolchain_config PRIVATE + mock_toolchain + ) + add_test(NAME test_toolchain_verify COMMAND test_toolchain_verify WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test ) + add_test(NAME test_toolchain_config COMMAND test_toolchain_config) endif() if(${BUILDCC_BUILD_AS_SINGLE_LIB}) @@ -53,7 +67,7 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) $ ) target_link_libraries(toolchain PUBLIC - env + schema ) endif() diff --git a/buildcc/lib/target/include/target/common/target_file_ext.h b/buildcc/lib/toolchain/include/toolchain/common/file_ext.h similarity index 88% rename from buildcc/lib/target/include/target/common/target_file_ext.h rename to buildcc/lib/toolchain/include/toolchain/common/file_ext.h index bab96289..64a35660 100644 --- a/buildcc/lib/target/include/target/common/target_file_ext.h +++ b/buildcc/lib/toolchain/include/toolchain/common/file_ext.h @@ -14,12 +14,12 @@ * limitations under the License. */ -#ifndef TARGET_COMMON_TARGET_FILE_EXT_H_ -#define TARGET_COMMON_TARGET_FILE_EXT_H_ +#ifndef TOOLCHAIN_COMMON_FILE_EXT_H_ +#define TOOLCHAIN_COMMON_FILE_EXT_H_ namespace buildcc { -enum class TargetFileExt { +enum class FileExt { Asm, ///< Valid Assembly source extension C, ///< Valid C source extension Cpp, ///< Valid Cpp source extension diff --git a/buildcc/lib/toolchain/include/toolchain/common/toolchain_config.h b/buildcc/lib/toolchain/include/toolchain/common/toolchain_config.h new file mode 100644 index 00000000..8cdcce3b --- /dev/null +++ b/buildcc/lib/toolchain/include/toolchain/common/toolchain_config.h @@ -0,0 +1,101 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAIN_COMMON_TOOLCHAIN_CONFIG_H_ +#define TOOLCHAIN_COMMON_TOOLCHAIN_CONFIG_H_ + +#include +#include +#include + +#include "toolchain/common/file_ext.h" + +namespace fs = std::filesystem; + +namespace buildcc { + +struct ToolchainConfig { + ToolchainConfig() = default; + + /** + * @brief Get the valid file extension from a path + * + * See ToolchainConfig::valid_c_ext, ToolchainConfig::valid_cpp_ext, + * ToolchainConfig::valid_asm_ext, ToolchainConfig::valid_header_ext + * + * @param filepath Absolute / Relative path of the file + * @return FileExt File path detected as per Toolchain::valid_* + * variables + */ + FileExt GetFileExt(const fs::path &filepath) const; + + /** + * @brief Checks for C/C++ source file validity. + * + * See ToolchainConfig::valid_c_ext, ToolchainConfig::valid_cpp_ext, + * ToolchainConfig::valid_asm_ext + * + * @param filepath Absolute / Relative path of file + * @return true If file extension belongs to the above valid_* list + * @return false If file extension does not belong to the above valid_* list + */ + bool IsValidSource(const fs::path &filepath) const; + + /** + * @brief Checks for Header file validity + * + * See ToolchainConfig::valid_header_ext + * + * @param filepath Absolute / Relative path of file + * @return true If file extension belongs to above valid_* list + * @return false If file extension does not belong to above valid_* list + */ + bool IsValidHeader(const fs::path &filepath) const; + + /** + * @brief Expects Source file validity + * + * env::assert_fatal if not a valid source + * + * @param filepath Absolute / Relative path of file + */ + void ExpectsValidSource(const fs::path &filepath) const; + + /** + * @brief Expects header file validity + * + * env::assert_fatal if not a valid header + * + * @param filepath Absolute / Relative path of file + */ + void ExpectsValidHeader(const fs::path &filepath) const; + + std::string obj_ext{".o"}; + std::string pch_header_ext{".h"}; + std::string pch_compile_ext{".gch"}; + + std::string prefix_include_dir{"-I"}; + std::string prefix_lib_dir{"-L"}; + + std::unordered_set valid_c_ext{".c"}; + std::unordered_set valid_cpp_ext{".cpp", ".cxx", ".cc"}; + std::unordered_set valid_asm_ext{".s", ".S", ".asm"}; + std::unordered_set valid_header_ext{".h", ".hpp"}; +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index f46c3d41..dec04968 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -21,7 +21,9 @@ #include #include -#include "api/toolchain_verify.h" +#include "toolchain/common/toolchain_config.h" + +#include "toolchain/api/toolchain_verify.h" namespace buildcc { @@ -41,10 +43,13 @@ class Toolchain : public ToolchainVerify { explicit Toolchain(Id id, std::string_view name, std::string_view asm_compiler, std::string_view c_compiler, std::string_view cpp_compiler, std::string_view archiver, - std::string_view linker) + std::string_view linker, + const ToolchainConfig &config = ToolchainConfig()) : id_(id), name_(name), asm_compiler_(asm_compiler), c_compiler_(c_compiler), cpp_compiler_(cpp_compiler), - archiver_(archiver), linker_(linker) {} + archiver_(archiver), linker_(linker), config_(config) { + UpdateConfig(config_); + } Toolchain(Toolchain &&toolchain) = default; Toolchain(const Toolchain &toolchain) = delete; @@ -58,6 +63,11 @@ class Toolchain : public ToolchainVerify { const std::string &GetArchiver() const { return archiver_; } const std::string &GetLinker() const { return linker_; } + const ToolchainConfig &GetConfig() const { return config_; } + +private: + virtual void UpdateConfig(ToolchainConfig &config) { (void)config; } + private: friend class ToolchainVerify; @@ -69,6 +79,8 @@ class Toolchain : public ToolchainVerify { std::string cpp_compiler_; std::string archiver_; std::string linker_; + + ToolchainConfig config_; }; typedef Toolchain::Id ToolchainId; diff --git a/buildcc/lib/toolchain/src/common/toolchain_config.cpp b/buildcc/lib/toolchain/src/common/toolchain_config.cpp new file mode 100644 index 00000000..55125dd4 --- /dev/null +++ b/buildcc/lib/toolchain/src/common/toolchain_config.cpp @@ -0,0 +1,88 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "toolchain/common/toolchain_config.h" + +#include "env/assert_fatal.h" + +#include "schema/path.h" + +#include "fmt/format.h" + +namespace buildcc { + +FileExt ToolchainConfig::GetFileExt(const fs::path &filepath) const { + if (!filepath.has_extension()) { + return FileExt::Invalid; + } + + FileExt type = FileExt::Invalid; + const std::string ext = filepath.extension().string(); + + if (valid_c_ext.count(ext) == 1) { + type = FileExt::C; + } else if (valid_cpp_ext.count(ext) == 1) { + type = FileExt::Cpp; + } else if (valid_asm_ext.count(ext) == 1) { + type = FileExt::Asm; + } else if (valid_header_ext.count(ext) == 1) { + type = FileExt::Header; + } + + return type; +} + +bool ToolchainConfig::IsValidSource(const fs::path &filepath) const { + if (!filepath.has_extension()) { + return false; + } + + const std::string ext = filepath.extension().string(); + bool valid = false; + if ((valid_c_ext.find(ext) != valid_c_ext.end()) || + (valid_cpp_ext.find(ext) != valid_cpp_ext.end()) || + (valid_asm_ext.find(ext) != valid_asm_ext.end())) { + valid = true; + } + return valid; +} + +void ToolchainConfig::ExpectsValidSource(const fs::path &filepath) const { + env::assert_fatal( + IsValidSource(filepath), + fmt::format("{} does not have a valid source extension", filepath)); +} + +bool ToolchainConfig::IsValidHeader(const fs::path &filepath) const { + if (!filepath.has_extension()) { + return {}; + } + + const std::string ext = filepath.extension().string(); + bool valid = false; + if ((valid_header_ext.find(ext) != valid_header_ext.end())) { + valid = true; + } + return valid; +} + +void ToolchainConfig::ExpectsValidHeader(const fs::path &filepath) const { + env::assert_fatal( + IsValidHeader(filepath), + fmt::format("{} does not have a valid header extension", filepath)); +} + +} // namespace buildcc diff --git a/buildcc/lib/toolchain/test/test_toolchain_config.cpp b/buildcc/lib/toolchain/test/test_toolchain_config.cpp new file mode 100644 index 00000000..a0cfce24 --- /dev/null +++ b/buildcc/lib/toolchain/test/test_toolchain_config.cpp @@ -0,0 +1,41 @@ +#include "toolchain/common/toolchain_config.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" + +// clang-format off +TEST_GROUP(ToolchainConfigTestGroup) +{ +}; +// clang-format on + +TEST(ToolchainConfigTestGroup, GetFileExt) { + buildcc::ToolchainConfig toolchain_config; + + buildcc::FileExt ext; + + ext = toolchain_config.GetFileExt("file.asm"); + CHECK(ext == buildcc::FileExt::Asm); + + ext = toolchain_config.GetFileExt("file.c"); + CHECK(ext == buildcc::FileExt::C); + + ext = toolchain_config.GetFileExt("file.cpp"); + CHECK(ext == buildcc::FileExt::Cpp); + + ext = toolchain_config.GetFileExt("file.h"); + CHECK(ext == buildcc::FileExt::Header); + + ext = toolchain_config.GetFileExt("file.invalid"); + CHECK(ext == buildcc::FileExt::Invalid); + + ext = toolchain_config.GetFileExt("random/directory"); + CHECK(ext == buildcc::FileExt::Invalid); +} + +int main(int ac, char **av) { + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake index 99d9949c..a3d21867 100644 --- a/buildcc/schema/cmake/schema.cmake +++ b/buildcc/schema/cmake/schema.cmake @@ -68,6 +68,9 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) $ $ ) + target_link_libraries(schema PUBLIC + env + ) target_include_directories(schema PRIVATE ${SCHEMA_BUILD_DIR} ) @@ -75,7 +78,6 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) target_link_options(schema PRIVATE ${BUILD_LINK_FLAGS}) target_link_libraries(schema PRIVATE flatbuffers_header_only - env ) add_dependencies(schema fbs_to_header) endif() diff --git a/buildcc/targets/include/targets/target_gcc.h b/buildcc/targets/include/targets/target_gcc.h index 60df007f..2e2dfb32 100644 --- a/buildcc/targets/include/targets/target_gcc.h +++ b/buildcc/targets/include/targets/target_gcc.h @@ -29,14 +29,6 @@ constexpr const char *const kGccExecutableExt = ""; constexpr const char *const kGccStaticLibExt = ".a"; constexpr const char *const kGccDynamicLibExt = ".so"; -constexpr const char *const kGccObjExt = ".o"; -constexpr const char *const kGccPchHeaderExt = ".h"; -constexpr const char *const kGccPchCompileExt = ".gch"; - -// GCC -constexpr const char *const kGccPrefixIncludeDir = "-I"; -constexpr const char *const kGccPrefixLibDir = "-L"; - constexpr const char *const kGccGenericPchCompileCommand = "{compiler} {preprocessor_flags} {include_dirs} {common_compile_flags} " "{pch_compile_flags} {compile_flags} -o {output} -c {input}"; @@ -72,11 +64,6 @@ class GccConfig : ConfigInterface { const std::string &link_command) { TargetConfig config; config.target_ext = target_ext; - config.obj_ext = kGccObjExt; - config.pch_header_ext = kGccPchHeaderExt; - config.pch_compile_ext = kGccPchCompileExt; - std::string prefix_include_dir = kGccPrefixIncludeDir; - std::string prefix_lib_dir = kGccPrefixLibDir; config.pch_command = kGccGenericPchCompileCommand; config.compile_command = compile_command; config.link_command = link_command; diff --git a/buildcc/targets/include/targets/target_mingw.h b/buildcc/targets/include/targets/target_mingw.h index 44f93720..abaeeb38 100644 --- a/buildcc/targets/include/targets/target_mingw.h +++ b/buildcc/targets/include/targets/target_mingw.h @@ -54,11 +54,6 @@ class MingwConfig : ConfigInterface { const std::string &link_command) { TargetConfig config; config.target_ext = target_ext; - config.obj_ext = kGccObjExt; - config.pch_header_ext = kGccPchHeaderExt; - config.pch_compile_ext = kGccPchCompileExt; - std::string prefix_include_dir = kGccPrefixIncludeDir; - std::string prefix_lib_dir = kGccPrefixLibDir; config.pch_command = kGccGenericPchCompileCommand; config.compile_command = compile_command; config.link_command = link_command; diff --git a/buildcc/targets/include/targets/target_msvc.h b/buildcc/targets/include/targets/target_msvc.h index 0d8e91ae..7baaae88 100644 --- a/buildcc/targets/include/targets/target_msvc.h +++ b/buildcc/targets/include/targets/target_msvc.h @@ -33,13 +33,6 @@ constexpr const char *const kMsvcStaticLibExt = ".lib"; // OUT .dll needs to be present in the executable folder during runtime constexpr const char *const kMsvcDynamicLibExt = ".lib"; -constexpr const char *const kMsvcObjExt = ".obj"; -constexpr const char *const kMsvcPchHeaderExt = ".h"; -constexpr const char *const kMsvcPchCompileExt = ".pch"; - -constexpr const char *const kMsvcPrefixIncludeDir = "/I"; -constexpr const char *const kMsvcPrefixLibDir = "/LIBPATH:"; - constexpr const char *const kMsvcPchCompileCommand = "{compiler} {preprocessor_flags} {include_dirs} {common_compile_flags} " "/Yc{input} /FI{input} /Fp{output} {pch_compile_flags} {compile_flags} " @@ -79,11 +72,6 @@ class MsvcConfig : ConfigInterface { const std::string &link_command) { TargetConfig config; config.target_ext = target_ext; - config.obj_ext = kMsvcObjExt; - config.pch_header_ext = kMsvcPchHeaderExt; - config.pch_compile_ext = kMsvcPchCompileExt; - config.prefix_include_dir = kMsvcPrefixIncludeDir; - config.prefix_lib_dir = kMsvcPrefixLibDir; config.pch_command = kMsvcPchCompileCommand; config.compile_command = compile_command; config.link_command = link_command; diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index b7c490fb..ebf4be40 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -21,6 +21,12 @@ namespace buildcc { +constexpr const char *const kGccObjExt = ".o"; +constexpr const char *const kGccPchHeaderExt = ".h"; +constexpr const char *const kGccPchCompileExt = ".gch"; +constexpr const char *const kGccPrefixIncludeDir = "-I"; +constexpr const char *const kGccPrefixLibDir = "-L"; + /** * @brief Generic GCC Toolchain
* id = ToolchainId::Gcc
@@ -36,6 +42,15 @@ class Toolchain_gcc : public Toolchain { Toolchain_gcc() : Toolchain(Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld") {} Toolchain_gcc(const Toolchain_gcc &gcc) = delete; + +private: + void UpdateConfig(ToolchainConfig &config) override { + config.obj_ext = kGccObjExt; + config.pch_header_ext = kGccPchHeaderExt; + config.pch_compile_ext = kGccPchCompileExt; + config.prefix_include_dir = kGccPrefixIncludeDir; + config.prefix_lib_dir = kGccPrefixLibDir; + } }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index 44d4b09b..05bef7ca 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -21,6 +21,12 @@ namespace buildcc { +constexpr const char *const kMingwObjExt = ".o"; +constexpr const char *const kMingwPchHeaderExt = ".h"; +constexpr const char *const kMingwPchCompileExt = ".gch"; +constexpr const char *const kMingwPrefixIncludeDir = "-I"; +constexpr const char *const kMingwPrefixLibDir = "-L"; + /** * @brief Generic MinGW Toolchain
* id = ToolchainId::MinGW
@@ -36,6 +42,15 @@ class Toolchain_mingw : public BaseToolchain { Toolchain_mingw() : Toolchain(ToolchainId::MinGW, "gcc", "as", "gcc", "g++", "ar", "ld") {} Toolchain_mingw(const Toolchain_mingw &) = delete; + +private: + void UpdateConfig(ToolchainConfig &config) { + config.obj_ext = kMingwObjExt; + config.pch_header_ext = kMingwPchHeaderExt; + config.pch_compile_ext = kMingwPchCompileExt; + config.prefix_include_dir = kMingwPrefixIncludeDir; + config.prefix_lib_dir = kMingwPrefixLibDir; + } }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index f74a479d..6a5a8ceb 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -21,6 +21,13 @@ namespace buildcc { +constexpr const char *const kMsvcObjExt = ".obj"; +constexpr const char *const kMsvcPchHeaderExt = ".h"; +constexpr const char *const kMsvcPchCompileExt = ".pch"; + +constexpr const char *const kMsvcPrefixIncludeDir = "/I"; +constexpr const char *const kMsvcPrefixLibDir = "/LIBPATH:"; + /** * @brief Generic GCC Toolchain
* id = ToolchainId::Msvc
@@ -37,6 +44,15 @@ class Toolchain_msvc : public Toolchain { : Toolchain(Toolchain::Id::Msvc, "msvc", "cl", "cl", "cl", "lib", "link") {} Toolchain_msvc(const Toolchain_msvc &gcc) = delete; + +private: + void UpdateConfig(ToolchainConfig &config) { + config.obj_ext = kMsvcObjExt; + config.pch_header_ext = kMsvcPchHeaderExt; + config.pch_compile_ext = kMsvcPchCompileExt; + config.prefix_include_dir = kMsvcPrefixIncludeDir; + config.prefix_lib_dir = kMsvcPrefixLibDir; + } }; } // namespace buildcc diff --git a/buildexe/src/build_env_setup.cpp b/buildexe/src/build_env_setup.cpp index 6884a1de..2bfcac96 100644 --- a/buildexe/src/build_env_setup.cpp +++ b/buildexe/src/build_env_setup.cpp @@ -194,31 +194,15 @@ struct BuildExeLibDir {{ } // Segregate valid lib files into sources and include dirs - internal::fs_unordered_set sources; - internal::fs_unordered_set include_dirs; - internal::fs_unordered_set headers; for (const auto &lib_build_file : buildexe_args_.GetLibBuildFiles()) { - if (user_target.GetConfig().IsValidSource(lib_build_file)) { - sources.insert(lib_build_file); + if (user_target.GetToolchain().GetConfig().IsValidSource(lib_build_file)) { + user_target.AddSourceAbsolute(lib_build_file); } - if (user_target.GetConfig().IsValidHeader(lib_build_file)) { - include_dirs.insert(lib_build_file.parent_path()); - headers.insert(lib_build_file); + if (user_target.GetToolchain().GetConfig().IsValidHeader(lib_build_file)) { + user_target.AddIncludeDirAbsolute(lib_build_file.parent_path(), false); + user_target.AddHeaderAbsolute(lib_build_file); } } - - // Add sources to user_target - for (const auto &s : sources) { - user_target.AddSourceAbsolute(s); - } - // Add include dirs to user_target - for (const auto &idir : include_dirs) { - user_target.AddIncludeDir(idir, false); - } - // Add headers to user_target - for (const auto &h : headers) { - user_target.AddHeaderAbsolute(h); - } } void BuildEnvSetup::UserTargetBuild() { diff --git a/doc/software_architecture/buildcc_interface_lib.PNG b/doc/software_architecture/buildcc_interface_lib.PNG index 729c9b080b8edeb307aeaa3a663ba9fd05c8df6a..e0ce861cdf35a76ad446c2d7baef8f91af99cc0d 100644 GIT binary patch literal 144370 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 register flatbuffers .up.> schema - - env -up-> toolchain env -up-> schema - taskflow -up-> target - schema -up-> target + schema -up-> toolchain + toolchain -up-> target + taskflow -up-> target toolchain -up-> toolchain_specialized target -up-> target_specialized diff --git a/docs/source/user_api/target_utils.rst b/docs/source/user_api/target_utils.rst index b85fc251..4940883f 100644 --- a/docs/source/user_api/target_utils.rst +++ b/docs/source/user_api/target_utils.rst @@ -3,11 +3,6 @@ Target Utils Commonly used Utils (Classes / Structs) for **Generator**, **TargetInfo** and **Target** classes. -target_file_ext.h ------------------- - -.. doxygenenum:: buildcc::TargetFileExt - target_type.h -------------- diff --git a/docs/source/user_api/toc.rst b/docs/source/user_api/toc.rst index c149c8cd..c7c858d8 100644 --- a/docs/source/user_api/toc.rst +++ b/docs/source/user_api/toc.rst @@ -6,6 +6,7 @@ User API args register + toolchain_utils toolchain target_utils generator diff --git a/docs/source/user_api/toolchain_utils.rst b/docs/source/user_api/toolchain_utils.rst new file mode 100644 index 00000000..0e812633 --- /dev/null +++ b/docs/source/user_api/toolchain_utils.rst @@ -0,0 +1,14 @@ +Toolchain Utils +================ + +Commonly used Utils (Classes / Structs) for **Toolchain** + +file_ext.h +------------ + +.. doxygenenum:: buildcc::FileExt + +toolchain_config.h +-------------------- + +.. doxygenstruct:: buildcc::ToolchainConfig diff --git a/example/hybrid/target_info/build.cpp b/example/hybrid/target_info/build.cpp index 25aa1a4a..3fb2cf26 100644 --- a/example/hybrid/target_info/build.cpp +++ b/example/hybrid/target_info/build.cpp @@ -33,8 +33,10 @@ int main(int argc, char **argv) { Toolchain_msvc msvc; // TargetInfo - TargetInfo genericadd_ho("files"); - reg.Callback(genericadd_ho_cb, genericadd_ho); + TargetInfo gcc_genericadd_ho(gcc, "files"); + TargetInfo msvc_genericadd_ho(msvc, "files"); + reg.Callback(genericadd_ho_cb, gcc_genericadd_ho); + reg.Callback(genericadd_ho_cb, msvc_genericadd_ho); ExecutableTarget_gcc g_genericadd1("generic_add_1", gcc, "files"); ExecutableTarget_msvc m_genericadd1("generic_add_1", msvc, "files"); @@ -43,11 +45,15 @@ int main(int argc, char **argv) { ExecutableTarget_msvc m_genericadd2("generic_add_2", msvc, "files"); // Select your builds and tests using the .toml files - reg.Build(arg_gcc.state, genericadd1_build_cb, g_genericadd1, genericadd_ho); - reg.Build(arg_msvc.state, genericadd1_build_cb, m_genericadd1, genericadd_ho); - - reg.Build(arg_gcc.state, genericadd2_build_cb, g_genericadd2, genericadd_ho); - reg.Build(arg_msvc.state, genericadd2_build_cb, m_genericadd2, genericadd_ho); + reg.Build(arg_gcc.state, genericadd1_build_cb, g_genericadd1, + gcc_genericadd_ho); + reg.Build(arg_gcc.state, genericadd2_build_cb, g_genericadd2, + gcc_genericadd_ho); + + reg.Build(arg_msvc.state, genericadd1_build_cb, m_genericadd1, + msvc_genericadd_ho); + reg.Build(arg_msvc.state, genericadd2_build_cb, m_genericadd2, + msvc_genericadd_ho); // 5. Test steps // NOTE, For now they are just dummy callbacks From 900766466e50dbfd01787fdfb943f58963a4aa9a Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Feb 2022 13:16:21 -0800 Subject: [PATCH 04/35] Enable BUILDCC_TESTING for MSVC (#195) --- .github/workflows/linux_gcc_cmake_build.yml | 2 +- .github/workflows/win_cmake_build.yml | 8 ++- CMakeLists.txt | 4 +- CMakePresets.json | 2 +- buildcc/lib/args/CMakeLists.txt | 2 +- buildcc/lib/args/test/test_args.cpp | 1 + buildcc/lib/env/CMakeLists.txt | 2 +- buildcc/lib/env/include/env/util.h | 2 +- buildcc/lib/env/test/test_env_util.cpp | 64 ++++++++++--------- buildcc/lib/target/cmake/mock_target.cmake | 2 +- buildcc/lib/target/mock/test_target_util.h | 22 +++++++ buildcc/lib/target/test/path/CMakeLists.txt | 2 +- .../lib/target/test/target/test_generator.cpp | 5 +- .../test/target/test_target_external_lib.cpp | 1 - .../test/target/test_target_lib_dep.cpp | 4 +- .../target/test/target/test_target_pch.cpp | 7 +- .../target/test/target/test_target_source.cpp | 5 +- .../test/target/test_target_user_deps.cpp | 7 +- buildcc/lib/toolchain/CMakeLists.txt | 2 +- .../toolchain/test/test_toolchain_verify.cpp | 60 +++++++++-------- buildcc/plugins/CMakeLists.txt | 2 +- buildcc/plugins/src/buildcc_find.cpp | 23 ++----- buildcc/schema/cmake/schema.cmake | 2 +- cmake/flags/test_flags.cmake | 11 ++-- 24 files changed, 132 insertions(+), 110 deletions(-) create mode 100644 buildcc/lib/target/mock/test_target_util.h diff --git a/.github/workflows/linux_gcc_cmake_build.yml b/.github/workflows/linux_gcc_cmake_build.yml index 4b25ca9c..a159ea7d 100644 --- a/.github/workflows/linux_gcc_cmake_build.yml +++ b/.github/workflows/linux_gcc_cmake_build.yml @@ -191,7 +191,7 @@ jobs: working-directory: ${{github.workspace}}/${{env.BUILD_FOLDER_DEV_SINGLE}} run: cmake --build . --target cppcheck_static_analysis - - name: Build Debug for test + - name: Build Debug and test # Linux has 2 cores run: | cmake --build --list-presets diff --git a/.github/workflows/win_cmake_build.yml b/.github/workflows/win_cmake_build.yml index 2bcadad4..1d4a1098 100644 --- a/.github/workflows/win_cmake_build.yml +++ b/.github/workflows/win_cmake_build.yml @@ -44,7 +44,13 @@ jobs: cmake --list-presets cmake --preset=${{env.BUILD_MSVC_PRESET}} - - name: Build + - name: Build Debug and test + working-directory: ${{github.workspace}}/${{env.BUILD_FOLDER_MSVC_DEV_ALL}} + run: | + cmake --build . --parallel 2 --config Debug + ctest . --parallel 2 -C Debug + + - name: Build Release # Linux has 2 cores run: | cmake --build --list-presets diff --git a/CMakeLists.txt b/CMakeLists.txt index 68e47918..fa0f8d19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ endif() # Testing set(BUILD_TESTING OFF CACHE BOOL "Third Party modules use these options") -if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" AND ${BUILDCC_TESTING}) +if (${BUILDCC_TESTING}) set(TESTING ON) message("Enabling unit-testing") message("Compiler identification: ${CMAKE_CXX_COMPILER_ID}") @@ -85,7 +85,7 @@ endif() # Coverage -if (${TESTING}) +if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" AND ${TESTING}) include(cmake/coverage/lcov.cmake) include(cmake/coverage/gcovr.cmake) endif() diff --git a/CMakePresets.json b/CMakePresets.json index 68fb595c..fcc2836a 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -121,7 +121,7 @@ "BUILDCC_BOOTSTRAP_THROUGH_CMAKE": true, "BUILDCC_PRECOMPILE_HEADERS": true, "BUILDCC_EXAMPLES": true, - "BUILDCC_TESTING": false, + "BUILDCC_TESTING": true, "BUILDCC_CLANGTIDY": false, "BUILDCC_CPPCHECK": false, "BUILDCC_DOCUMENTATION": false, diff --git a/buildcc/lib/args/CMakeLists.txt b/buildcc/lib/args/CMakeLists.txt index c2f2d3a3..ffc289fa 100644 --- a/buildcc/lib/args/CMakeLists.txt +++ b/buildcc/lib/args/CMakeLists.txt @@ -22,7 +22,7 @@ target_link_libraries(mock_args PUBLIC CppUTest CppUTestExt - gcov + ${TEST_LINK_LIBS} ) # Tests diff --git a/buildcc/lib/args/test/test_args.cpp b/buildcc/lib/args/test/test_args.cpp index 21bf1a75..7a686577 100644 --- a/buildcc/lib/args/test/test_args.cpp +++ b/buildcc/lib/args/test/test_args.cpp @@ -258,5 +258,6 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { } int main(int ac, char **av) { + MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/env/CMakeLists.txt b/buildcc/lib/env/CMakeLists.txt index ecc6080b..93afa078 100644 --- a/buildcc/lib/env/CMakeLists.txt +++ b/buildcc/lib/env/CMakeLists.txt @@ -20,7 +20,7 @@ if (${TESTING}) CppUTest CppUTestExt - gcov + ${TEST_LINK_LIBS} ) target_compile_options(mock_env PUBLIC ${TEST_COMPILE_FLAGS} ${BUILD_COMPILE_FLAGS}) target_link_options(mock_env PUBLIC ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS}) diff --git a/buildcc/lib/env/include/env/util.h b/buildcc/lib/env/include/env/util.h index be467b34..45a71448 100644 --- a/buildcc/lib/env/include/env/util.h +++ b/buildcc/lib/env/include/env/util.h @@ -49,7 +49,7 @@ namespace buildcc::env { */ inline bool save_file(const char *name, const char *buf, size_t len, bool binary) { - if (buf == nullptr) { + if (name == nullptr || buf == nullptr) { return false; } std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out); diff --git a/buildcc/lib/env/test/test_env_util.cpp b/buildcc/lib/env/test/test_env_util.cpp index cd1fe63c..3e6d867d 100644 --- a/buildcc/lib/env/test/test_env_util.cpp +++ b/buildcc/lib/env/test/test_env_util.cpp @@ -33,13 +33,6 @@ TEST(EnvUtilTestGroup, Util_SaveFile_NullptrName) { CHECK_FALSE(save); } -TEST(EnvUtilTestGroup, Util_SaveFile_BadWrite) { - constexpr const char *const FILENAME = "BadWrite.txt"; - fs::remove(FILENAME); - bool save = buildcc::env::save_file(FILENAME, "Hello", -1, false); - CHECK_FALSE(save); -} - TEST(EnvUtilTestGroup, Util_SaveFile_GoodWrite) { constexpr const char *const FILENAME = "GoodWrite.txt"; fs::remove(FILENAME); @@ -47,13 +40,6 @@ TEST(EnvUtilTestGroup, Util_SaveFile_GoodWrite) { CHECK_TRUE(save); } -TEST(EnvUtilTestGroup, Util_SaveFile_BadWrite_Binary) { - constexpr const char *const FILENAME = "BadWrite_Binary.txt"; - fs::remove(FILENAME); - bool save = buildcc::env::save_file(FILENAME, "Hello", -1, true); - CHECK_FALSE(save); -} - TEST(EnvUtilTestGroup, Util_SaveFile_GoodWrite_Binary) { constexpr const char *const FILENAME = "GoodWrite_Binary.txt"; fs::remove(FILENAME); @@ -69,22 +55,6 @@ TEST(EnvUtilTestGroup, Util_SaveFile_CheckDirectory) { CHECK_FALSE(save); } -TEST(EnvUtilTestGroup, Util_SaveFile_CannotWrite) { - constexpr const char *const FILENAME = "CannotWrite.txt"; - fs::remove(FILENAME); - bool save = buildcc::env::save_file(FILENAME, "Hello", false); - CHECK_TRUE(save); - - std::error_code err; - fs::permissions(FILENAME, fs::perms::none, err); - if (err) { - FAIL("Cannot disable file permissions"); - } - - save = buildcc::env::save_file(FILENAME, "Hello", false); - CHECK_FALSE(save); -} - // Load File TEST(EnvUtilTestGroup, Util_LoadFile_CheckDirectory) { // NOTE, This is a directory @@ -143,6 +113,8 @@ TEST(EnvUtilTestGroup, Util_LoadFile_ReadTxt) { CHECK_TRUE(load); } +#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__MINGW64__) + TEST(EnvUtilTestGroup, Util_LoadFile_CannotOpen) { constexpr const char *const FILENAME = "CannotOpen.txt"; buildcc::env::save_file(FILENAME, "Random Data", false); @@ -159,6 +131,38 @@ TEST(EnvUtilTestGroup, Util_LoadFile_CannotOpen) { CHECK_FALSE(load); } +TEST(EnvUtilTestGroup, Util_SaveFile_BadWrite_Binary) { + constexpr const char *const FILENAME = "BadWrite_Binary.txt"; + fs::remove(FILENAME); + bool save = buildcc::env::save_file(FILENAME, "Hello", -1, true); + CHECK_FALSE(save); +} + +TEST(EnvUtilTestGroup, Util_SaveFile_BadWrite) { + constexpr const char *const FILENAME = "BadWrite.txt"; + fs::remove(FILENAME); + bool save = buildcc::env::save_file(FILENAME, "Hello", -1, false); + CHECK_FALSE(save); +} + +TEST(EnvUtilTestGroup, Util_SaveFile_CannotWrite) { + constexpr const char *const FILENAME = "CannotWrite.txt"; + fs::remove(FILENAME); + bool save = buildcc::env::save_file(FILENAME, "Hello", false); + CHECK_TRUE(save); + + std::error_code err; + fs::permissions(FILENAME, fs::perms::none, err); + if (err) { + FAIL("Cannot disable file permissions"); + } + + save = buildcc::env::save_file(FILENAME, "Hello", false); + CHECK_FALSE(save); +} + +#endif + TEST(EnvUtilTestGroup, Util_Split) { { std::vector paths = buildcc::env::split("", ':'); diff --git a/buildcc/lib/target/cmake/mock_target.cmake b/buildcc/lib/target/cmake/mock_target.cmake index 39ec8a77..2d648938 100644 --- a/buildcc/lib/target/cmake/mock_target.cmake +++ b/buildcc/lib/target/cmake/mock_target.cmake @@ -25,7 +25,7 @@ target_link_libraries(mock_target PUBLIC CppUTest CppUTestExt - gcov + ${TEST_LINK_LIBS} ) # https://github.com/msys2/MINGW-packages/issues/2303 diff --git a/buildcc/lib/target/mock/test_target_util.h b/buildcc/lib/target/mock/test_target_util.h new file mode 100644 index 00000000..70bad12a --- /dev/null +++ b/buildcc/lib/target/mock/test_target_util.h @@ -0,0 +1,22 @@ +#ifndef TARGET_MOCK_TEST_TARGET_UTIL_H_ +#define TARGET_MOCK_TEST_TARGET_UTIL_H_ + +#ifdef _WIN32 +#include +#else +#include +#endif + +namespace buildcc::m { + +inline void blocking_sleep(int seconds) { +#ifdef _WIN32 + Sleep(seconds * 1000); +#else + sleep(seconds); +#endif +} + +} // namespace buildcc::m + +#endif diff --git a/buildcc/lib/target/test/path/CMakeLists.txt b/buildcc/lib/target/test/path/CMakeLists.txt index c6c9de0f..04d8d9dc 100644 --- a/buildcc/lib/target/test/path/CMakeLists.txt +++ b/buildcc/lib/target/test/path/CMakeLists.txt @@ -15,7 +15,7 @@ target_link_libraries(${TEST_NAME} PRIVATE CppUTest CppUTestExt - gcov + ${TEST_LINK_LIBS} ) target_compile_options(${TEST_NAME} PRIVATE ${TEST_COMPILE_FLAGS}) target_link_options(${TEST_NAME} PRIVATE ${TEST_LINK_FLAGS}) diff --git a/buildcc/lib/target/test/target/test_generator.cpp b/buildcc/lib/target/test/target/test_generator.cpp index 877b0deb..169e31cf 100644 --- a/buildcc/lib/target/test/target/test_generator.cpp +++ b/buildcc/lib/target/test/target/test_generator.cpp @@ -1,9 +1,8 @@ #include "target/generator.h" -#include - #include "expect_command.h" #include "expect_generator.h" +#include "test_target_util.h" #include "taskflow/taskflow.hpp" @@ -162,7 +161,7 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Inputs) { buildcc::m::GeneratorRunner(generator); } - sleep(1); + buildcc::m::blocking_sleep(1); bool saved = buildcc::env::save_file( (buildcc::env::get_project_root_dir() / "new_source.cpp") .string() diff --git a/buildcc/lib/target/test/target/test_target_external_lib.cpp b/buildcc/lib/target/test/target/test_target_external_lib.cpp index b081982d..7e12128e 100644 --- a/buildcc/lib/target/test/target/test_target_external_lib.cpp +++ b/buildcc/lib/target/test/target/test_target_external_lib.cpp @@ -10,7 +10,6 @@ #include "schema/target_serialization.h" #include -#include // NOTE, Make sure all these includes are AFTER the system and header includes #include "CppUTest/CommandLineTestRunner.h" diff --git a/buildcc/lib/target/test/target/test_target_lib_dep.cpp b/buildcc/lib/target/test/target/test_target_lib_dep.cpp index 5fc80122..a5cbda68 100644 --- a/buildcc/lib/target/test/target/test_target_lib_dep.cpp +++ b/buildcc/lib/target/test/target/test_target_lib_dep.cpp @@ -5,6 +5,7 @@ #include "expect_command.h" #include "expect_target.h" +#include "test_target_util.h" #include "target/target.h" @@ -12,7 +13,6 @@ #include "schema/target_serialization.h" #include -#include // NOTE, Make sure all these includes are AFTER the system and header includes #include "CppUTest/CommandLineTestRunner.h" @@ -234,7 +234,7 @@ TEST(TargetTestLibDep, TargetDep_UpdateExistingLibraryTest) { buildcc::m::TargetRunner(foolib); // * To make sure that save_file is newer - sleep(1); + buildcc::m::blocking_sleep(1); bool saved = buildcc::env::save_file( foolib.GetTargetPath().string().c_str(), std::string{""}, false); CHECK_TRUE(saved); diff --git a/buildcc/lib/target/test/target/test_target_pch.cpp b/buildcc/lib/target/test/target/test_target_pch.cpp index 4ce19edf..fcfc3653 100644 --- a/buildcc/lib/target/test/target/test_target_pch.cpp +++ b/buildcc/lib/target/test/target/test_target_pch.cpp @@ -1,11 +1,10 @@ #include -#include - #include "constants.h" #include "expect_command.h" #include "expect_target.h" +#include "test_target_util.h" #include "target/target.h" @@ -128,7 +127,7 @@ TEST(TargetPchTestGroup, Target_AddPch_Rebuild) { // Rebuild: Updated { - sleep(1); + buildcc::m::blocking_sleep(1); fs::path filename = fs::path(BUILD_SCRIPT_SOURCE) / "data" / "pch/pch_header_1.h"; bool save = buildcc::env::save_file(filename.string().c_str(), "", false); @@ -221,7 +220,7 @@ TEST(TargetPchTestGroup, Target_AddPch_CppRebuild) { // Rebuild: Updated { - sleep(1); + buildcc::m::blocking_sleep(1); fs::path filename = fs::path(BUILD_SCRIPT_SOURCE) / "data" / "pch/pch_header_1.h"; bool save = buildcc::env::save_file(filename.string().c_str(), "", false); diff --git a/buildcc/lib/target/test/target/test_target_source.cpp b/buildcc/lib/target/test/target/test_target_source.cpp index f2664083..45ed348f 100644 --- a/buildcc/lib/target/test/target/test_target_source.cpp +++ b/buildcc/lib/target/test/target/test_target_source.cpp @@ -1,9 +1,8 @@ #include "constants.h" -#include - #include "expect_command.h" #include "expect_target.h" +#include "test_target_util.h" #include "target/target.h" @@ -193,7 +192,7 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { CHECK_FALSE(loaded_sources.find(new_source_file) == loaded_sources.end()); } { - sleep(1); + buildcc::m::blocking_sleep(1); // * Force copy to trigger recompile for NEW_SOURCE // *2 Current file is updated diff --git a/buildcc/lib/target/test/target/test_target_user_deps.cpp b/buildcc/lib/target/test/target/test_target_user_deps.cpp index a6410a9a..8af6c4f0 100644 --- a/buildcc/lib/target/test/target/test_target_user_deps.cpp +++ b/buildcc/lib/target/test/target/test_target_user_deps.cpp @@ -1,9 +1,8 @@ -#include - #include "constants.h" #include "expect_command.h" #include "expect_target.h" +#include "test_target_util.h" #include "target/target.h" @@ -80,7 +79,7 @@ TEST(TargetTestUserDepsGroup, Target_Build_CompileDeps_Rebuild) { { // * To make sure that save_file is newer - sleep(1); + buildcc::m::blocking_sleep(1); const fs::path new_source = buildcc::env::get_project_root_dir() / "data" / "new_source.cpp"; std::string buf{""}; @@ -119,7 +118,7 @@ TEST(TargetTestUserDepsGroup, Target_Build_LinkDeps_Rebuild) { { // * To make sure that save_file is newer - sleep(1); + buildcc::m::blocking_sleep(1); const fs::path new_source = buildcc::env::get_project_root_dir() / "data" / "new_source.cpp"; std::string buf{""}; diff --git a/buildcc/lib/toolchain/CMakeLists.txt b/buildcc/lib/toolchain/CMakeLists.txt index 712131ff..6d8252a3 100644 --- a/buildcc/lib/toolchain/CMakeLists.txt +++ b/buildcc/lib/toolchain/CMakeLists.txt @@ -24,7 +24,7 @@ if (${TESTING}) CppUTest CppUTestExt - gcov + ${TEST_LINK_LIBS} ) add_executable(test_toolchain_verify diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index ad9a15f1..9e12df5e 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -175,34 +175,6 @@ TEST(ToolchainTestGroup, VerifyToolchain_PathContainsDir) { CHECK_TRUE(verified_toolchains.empty()); } -TEST(ToolchainTestGroup, VerifyToolchain_LockedFolder) { - std::error_code err; - fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::none, - err); - if (err) { - FAIL_TEST("Could not set file permissions"); - } - - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - buildcc::VerifyToolchainConfig config; - config.env_vars.clear(); - config.absolute_search_paths.push_back( - (fs::current_path() / "toolchains" / "gcc").string()); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(verified_toolchains.empty()); - - fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::all, - err); - if (err) { - FAIL_TEST("Could not set file permissions"); - } -} - TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_CompilerVersion) { buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); @@ -333,6 +305,38 @@ TEST(ToolchainTestGroup, VerifyToolchain_UpdateFalse) { CHECK_EQUAL(verified_toolchains.size(), 1); } +#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__MINGW64__) + +TEST(ToolchainTestGroup, VerifyToolchain_LockedFolder) { + std::error_code err; + fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::none, + err); + if (err) { + FAIL_TEST("Could not set file permissions"); + } + + buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + buildcc::VerifyToolchainConfig config; + config.env_vars.clear(); + config.absolute_search_paths.push_back( + (fs::current_path() / "toolchains" / "gcc").string()); + + std::vector verified_toolchains = + gcc.Verify(config); + UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); + CHECK_TRUE(verified_toolchains.empty()); + + fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::all, + err); + if (err) { + FAIL_TEST("Could not set file permissions"); + } +} + +#endif + int main(int ac, char **av) { buildcc::env::m::VectorStringCopier copier; mock().installCopier(TEST_VECTOR_STRING_TYPE, copier); diff --git a/buildcc/plugins/CMakeLists.txt b/buildcc/plugins/CMakeLists.txt index 42ae927b..0518831b 100644 --- a/buildcc/plugins/CMakeLists.txt +++ b/buildcc/plugins/CMakeLists.txt @@ -17,7 +17,7 @@ target_link_libraries(mock_plugins PUBLIC CppUTest CppUTestExt - gcov + ${TEST_LINK_LIBS} ) # Tests diff --git a/buildcc/plugins/src/buildcc_find.cpp b/buildcc/plugins/src/buildcc_find.cpp index 97a6e1c1..d60eaa34 100644 --- a/buildcc/plugins/src/buildcc_find.cpp +++ b/buildcc/plugins/src/buildcc_find.cpp @@ -22,6 +22,7 @@ #include "env/host_os_util.h" #include "env/logging.h" +#include "env/util.h" #include "schema/path.h" @@ -33,20 +34,6 @@ constexpr const char *const kOsNotSupported = "issue at https://github.com/coder137/build_in_cpp outlining your OS and " "usecase"; -std::vector SplitEnv(const char *env_ptr, const char *delim) { - std::vector env_paths; - - std::string temp{env_ptr}; - char *path = std::strtok(temp.data(), delim); - while (path != nullptr) { - env_paths.push_back( - buildcc::internal::Path::CreateNewPath(path).GetPathname()); - path = std::strtok(nullptr, delim); - } - - return env_paths; -} - std::vector SearchEnv(const std::string &host_env_var, const std::string ®ex) { char *path_ptr = std::getenv(host_env_var.c_str()); @@ -56,13 +43,13 @@ std::vector SearchEnv(const std::string &host_env_var, return {}; } - std::vector env_paths; constexpr const char *const kDelim = buildcc::env::get_os_envvar_delim(); if constexpr (kDelim == nullptr) { buildcc::env::log_critical(__FUNCTION__, kOsNotSupported); return {}; } - env_paths = SplitEnv(path_ptr, kDelim); + + std::vector env_paths = buildcc::env::split(path_ptr, kDelim[0]); // DONE, Construct a directory iterator // Only take the files @@ -71,12 +58,12 @@ std::vector SearchEnv(const std::string &host_env_var, std::error_code errcode; const auto dir_iter = fs::directory_iterator(env_p, errcode); if (errcode) { - buildcc::env::log_critical(env_p.string(), errcode.message()); + buildcc::env::log_critical(env_p, errcode.message()); continue; } for (const auto &dir_entry : dir_iter) { - if (!dir_entry.is_regular_file()) { + if (!dir_entry.path().has_filename()) { continue; } diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake index a3d21867..c7c1371a 100644 --- a/buildcc/schema/cmake/schema.cmake +++ b/buildcc/schema/cmake/schema.cmake @@ -22,7 +22,7 @@ if (${TESTING}) CppUTest CppUTestExt - gcov + ${TEST_LINK_LIBS} ) add_dependencies(mock_schema fbs_to_header) diff --git a/cmake/flags/test_flags.cmake b/cmake/flags/test_flags.cmake index bb8d8758..5846fab7 100644 --- a/cmake/flags/test_flags.cmake +++ b/cmake/flags/test_flags.cmake @@ -1,4 +1,7 @@ -set(TEST_COMPILE_FLAGS -g -Og -fprofile-arcs -ftest-coverage -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-inline -fprofile-abs-path -) -set(TEST_LINK_FLAGS -g -Og -fprofile-arcs -ftest-coverage -fprofile-abs-path -) +if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + set(TEST_COMPILE_FLAGS -g -Og -fprofile-arcs -ftest-coverage -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-inline -fprofile-abs-path + ) + set(TEST_LINK_FLAGS -g -Og -fprofile-arcs -ftest-coverage -fprofile-abs-path + ) + set(TEST_LINK_LIBS gcov) +endif() From 06bed3903e859dfd0fca71e947e0200ddb586ab0 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Feb 2022 20:47:30 -0800 Subject: [PATCH 05/35] Function lock segregation with Target state (#196) --- .../include/target/common/function_lock.h | 48 +++++++++++++++++++ .../include/target/common/target_state.h | 31 +++++------- buildcc/lib/target/include/target/target.h | 3 -- .../lib/target/include/target/target_info.h | 2 + buildcc/lib/target/src/api/deps_api.cpp | 4 +- buildcc/lib/target/src/api/flag_api.cpp | 16 +++---- buildcc/lib/target/src/api/include_api.cpp | 4 +- buildcc/lib/target/src/api/lib_api.cpp | 6 +-- buildcc/lib/target/src/api/pch_api.cpp | 2 +- buildcc/lib/target/src/api/source_api.cpp | 2 +- buildcc/lib/target/src/api/sync_api.cpp | 4 +- buildcc/lib/target/src/api/target_getter.cpp | 6 +-- .../lib/target/src/api/target_info_getter.cpp | 4 +- .../lib/target/src/common/target_state.cpp | 22 +++------ buildcc/lib/target/src/target/build.cpp | 8 ++-- .../target/src/target/friend/compile_pch.cpp | 6 +-- buildcc/lib/target/src/target/tasks.cpp | 2 +- .../target/test/target/test_target_state.cpp | 22 ++++----- 18 files changed, 112 insertions(+), 80 deletions(-) create mode 100644 buildcc/lib/target/include/target/common/function_lock.h diff --git a/buildcc/lib/target/include/target/common/function_lock.h b/buildcc/lib/target/include/target/common/function_lock.h new file mode 100644 index 00000000..3f15bddf --- /dev/null +++ b/buildcc/lib/target/include/target/common/function_lock.h @@ -0,0 +1,48 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TARGET_COMMON_FUNCTION_LOCK_H_ +#define TARGET_COMMON_FUNCTION_LOCK_H_ + +#include + +#include "fmt/format.h" + +#include "env/assert_fatal.h" + +namespace buildcc { + +class FunctionLock { +public: + void Lock() { lock_ = true; } + void Unlock() { lock_ = false; } + bool IsLocked() const { return lock_; } + void ExpectsUnlock(std::string_view tag) const { + env::assert_fatal(!lock_, + fmt::format("Cannot use {} when lock == true", tag)); + } + void ExpectsLock(std::string_view tag) const { + env::assert_fatal(lock_, + fmt::format("Cannot use {} when lock == false", tag)); + } + +private: + bool lock_{false}; +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/lib/target/include/target/common/target_state.h b/buildcc/lib/target/include/target/common/target_state.h index 3afc766f..bd211456 100644 --- a/buildcc/lib/target/include/target/common/target_state.h +++ b/buildcc/lib/target/include/target/common/target_state.h @@ -21,31 +21,24 @@ namespace buildcc { -// TODO, Seperate TargetState into lock_ and other internal boolean variables -// NOTE, This is because apart from lock_ every other parameter is updated -// during `Target::Build` -// TargetInfo does not have a `Build` method, it is only meant to hold -// information struct TargetState { - void SetSourceState(FileExt file_extension); - void SetPch(); - void SetLock(); - - void ExpectsUnlock() const; - void ExpectsLock() const; - // TODO, IsLocked + void BuildCompleted(); + void SourceDetected(FileExt file_extension); + void PchDetected(); + bool IsBuilt() const { return build_; } bool ContainsPch() const { return contains_pch_; } - - // TODO, Make these private getters - bool contains_asm{false}; - bool contains_c{false}; - bool contains_cpp{false}; - bool build{false}; - bool lock{false}; + bool ContainsAsm() const { return contains_asm_; } + bool ContainsC() const { return contains_c_; } + bool ContainsCpp() const { return contains_cpp_; } private: + bool build_{false}; + bool contains_pch_{false}; + bool contains_asm_{false}; + bool contains_c_{false}; + bool contains_cpp_{false}; }; } // namespace buildcc diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index a9540a14..ed72277f 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -75,8 +75,6 @@ class Target : public internal::BuilderInterface, env.GetTargetBuildDir() / toolchain.GetName() / name), config), name_(name), type_(type), - // toolchain_(toolchain), - // loader_(name, env_.GetTargetBuildDir()), serialization_(env_.GetTargetBuildDir() / fmt::format("{}.bin", name)), compile_pch_(*this), compile_object_(*this), link_target_(*this) { Initialize(); @@ -141,7 +139,6 @@ class Target : public internal::BuilderInterface, private: std::string name_; TargetType type_; - // const Toolchain &toolchain_; internal::TargetSerialization serialization_; // Friend classes diff --git a/buildcc/lib/target/include/target/target_info.h b/buildcc/lib/target/include/target/target_info.h index fb795161..98115a51 100644 --- a/buildcc/lib/target/include/target/target_info.h +++ b/buildcc/lib/target/include/target/target_info.h @@ -21,6 +21,7 @@ #include "toolchain/toolchain.h" +#include "target/common/function_lock.h" #include "target/common/target_config.h" #include "target/common/target_env.h" #include "target/common/target_state.h" @@ -88,6 +89,7 @@ class TargetInfo : public internal::SourceApi, UserTargetSchema user_; + FunctionLock lock_; TargetState state_; }; diff --git a/buildcc/lib/target/src/api/deps_api.cpp b/buildcc/lib/target/src/api/deps_api.cpp index 8cbee764..18a7c820 100644 --- a/buildcc/lib/target/src/api/deps_api.cpp +++ b/buildcc/lib/target/src/api/deps_api.cpp @@ -24,14 +24,14 @@ template void DepsApi::AddCompileDependencyAbsolute(const fs::path &absolute_path) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.compile_dependencies.insert(absolute_path); } template void DepsApi::AddLinkDependencyAbsolute(const fs::path &absolute_path) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.link_dependencies.insert(absolute_path); } diff --git a/buildcc/lib/target/src/api/flag_api.cpp b/buildcc/lib/target/src/api/flag_api.cpp index 99a9f294..856b46bb 100644 --- a/buildcc/lib/target/src/api/flag_api.cpp +++ b/buildcc/lib/target/src/api/flag_api.cpp @@ -24,55 +24,55 @@ template void FlagApi::AddPreprocessorFlag(const std::string &flag) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.preprocessor_flags.insert(flag); } template void FlagApi::AddCommonCompileFlag(const std::string &flag) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.common_compile_flags.insert(flag); } template void FlagApi::AddPchCompileFlag(const std::string &flag) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.pch_compile_flags.insert(flag); } template void FlagApi::AddPchObjectFlag(const std::string &flag) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.pch_object_flags.insert(flag); } template void FlagApi::AddAsmCompileFlag(const std::string &flag) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.asm_compile_flags.insert(flag); } template void FlagApi::AddCCompileFlag(const std::string &flag) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.c_compile_flags.insert(flag); } template void FlagApi::AddCppCompileFlag(const std::string &flag) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.cpp_compile_flags.insert(flag); } template void FlagApi::AddLinkFlag(const std::string &flag) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.link_flags.insert(flag); } diff --git a/buildcc/lib/target/src/api/include_api.cpp b/buildcc/lib/target/src/api/include_api.cpp index 49ca6241..66baa44e 100644 --- a/buildcc/lib/target/src/api/include_api.cpp +++ b/buildcc/lib/target/src/api/include_api.cpp @@ -24,7 +24,7 @@ template void IncludeApi::AddHeaderAbsolute(const fs::path &absolute_filepath) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); t.user_.headers.insert(absolute_filepath); } @@ -74,7 +74,7 @@ void IncludeApi::AddIncludeDirAbsolute(const fs::path &absolute_include_dir, bool glob_headers) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.include_dirs.insert(absolute_include_dir); if (glob_headers) { diff --git a/buildcc/lib/target/src/api/lib_api.cpp b/buildcc/lib/target/src/api/lib_api.cpp index 16eb85a8..aa15898a 100644 --- a/buildcc/lib/target/src/api/lib_api.cpp +++ b/buildcc/lib/target/src/api/lib_api.cpp @@ -25,7 +25,7 @@ template void LibApi::AddLibDirAbsolute(const fs::path &absolute_lib_dir) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.lib_dirs.insert(absolute_lib_dir); } @@ -40,14 +40,14 @@ void LibApi::AddLibDir(const fs::path &relative_lib_dir) { template void LibApi::AddLibDep(const BaseTarget &lib_dep) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.libs.push_back(lib_dep.GetTargetPath()); } template void LibApi::AddLibDep(const std::string &lib_dep) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.external_libs.push_back(lib_dep); } diff --git a/buildcc/lib/target/src/api/pch_api.cpp b/buildcc/lib/target/src/api/pch_api.cpp index c0695342..35fc16bf 100644 --- a/buildcc/lib/target/src/api/pch_api.cpp +++ b/buildcc/lib/target/src/api/pch_api.cpp @@ -24,7 +24,7 @@ template void PchApi::AddPchAbsolute(const fs::path &absolute_filepath) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); const fs::path absolute_pch = fs::path(absolute_filepath).make_preferred(); diff --git a/buildcc/lib/target/src/api/source_api.cpp b/buildcc/lib/target/src/api/source_api.cpp index cc47cda3..99676c15 100644 --- a/buildcc/lib/target/src/api/source_api.cpp +++ b/buildcc/lib/target/src/api/source_api.cpp @@ -24,7 +24,7 @@ template void SourceApi::AddSourceAbsolute(const fs::path &absolute_source) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); t.toolchain_.GetConfig().ExpectsValidSource(absolute_source); t.user_.sources.emplace(fs::path(absolute_source).make_preferred()); } diff --git a/buildcc/lib/target/src/api/sync_api.cpp b/buildcc/lib/target/src/api/sync_api.cpp index 261eca24..e947fb56 100644 --- a/buildcc/lib/target/src/api/sync_api.cpp +++ b/buildcc/lib/target/src/api/sync_api.cpp @@ -41,7 +41,7 @@ template void SyncApi::SpecializedCopy(TargetType target, std::initializer_list options) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); for (const SyncOption o : options) { switch (o) { case SyncOption::PreprocessorFlags: @@ -122,7 +122,7 @@ template void SyncApi::SpecializedInsert(TargetType target, std::initializer_list options) { T &t = static_cast(*this); - t.state_.ExpectsUnlock(); + t.lock_.ExpectsUnlock(__FUNCTION__); for (const SyncOption o : options) { switch (o) { case SyncOption::PreprocessorFlags: diff --git a/buildcc/lib/target/src/api/target_getter.cpp b/buildcc/lib/target/src/api/target_getter.cpp index e49e30ef..0c490c25 100644 --- a/buildcc/lib/target/src/api/target_getter.cpp +++ b/buildcc/lib/target/src/api/target_getter.cpp @@ -69,7 +69,7 @@ const std::string & TargetGetter::GetCompileCommand(const fs::path &source) const { const T &t = static_cast(*this); - t.state_.ExpectsLock(); + t.lock_.ExpectsLock(__FUNCTION__); return t.compile_object_.GetObjectData(source).command; } @@ -77,14 +77,14 @@ template const std::string &TargetGetter::GetLinkCommand() const { const T &t = static_cast(*this); - t.state_.ExpectsLock(); + t.lock_.ExpectsLock(__FUNCTION__); return t.link_target_.GetCommand(); } template tf::Taskflow &TargetGetter::GetTaskflow() { T &t = static_cast(*this); - t.state_.ExpectsLock(); + t.lock_.ExpectsLock(__FUNCTION__); return t.tf_; } diff --git a/buildcc/lib/target/src/api/target_info_getter.cpp b/buildcc/lib/target/src/api/target_info_getter.cpp index 488818a7..7efdc88a 100644 --- a/buildcc/lib/target/src/api/target_info_getter.cpp +++ b/buildcc/lib/target/src/api/target_info_getter.cpp @@ -30,13 +30,13 @@ template const TargetState &TargetInfoGetter::GetState() const { template bool TargetInfoGetter::IsBuilt() const { const T &t = static_cast(*this); - return t.state_.build; + return t.state_.IsBuilt(); } template bool TargetInfoGetter::IsLocked() const { const T &t = static_cast(*this); - return t.state_.lock; + return t.lock_.IsLocked(); } // Target Env diff --git a/buildcc/lib/target/src/common/target_state.cpp b/buildcc/lib/target/src/common/target_state.cpp index 95a8a022..a8e5cc65 100644 --- a/buildcc/lib/target/src/common/target_state.cpp +++ b/buildcc/lib/target/src/common/target_state.cpp @@ -20,16 +20,18 @@ namespace buildcc { -void TargetState::SetSourceState(FileExt file_extension) { +void TargetState::BuildCompleted() { build_ = true; } + +void TargetState::SourceDetected(FileExt file_extension) { switch (file_extension) { case FileExt::Asm: - contains_asm = true; + contains_asm_ = true; break; case FileExt::C: - contains_c = true; + contains_c_ = true; break; case FileExt::Cpp: - contains_cpp = true; + contains_cpp_ = true; break; case FileExt::Header: case FileExt::Invalid: @@ -38,16 +40,6 @@ void TargetState::SetSourceState(FileExt file_extension) { } } -void TargetState::SetPch() { contains_pch_ = true; } - -void TargetState::SetLock() { lock = true; } - -void TargetState::ExpectsUnlock() const { - env::assert_fatal(!lock, "Cannot use this function when lock == true"); -} - -void TargetState::ExpectsLock() const { - env::assert_fatal(lock, "Cannot use this function when lock == false"); -} +void TargetState::PchDetected() { contains_pch_ = true; } } // namespace buildcc diff --git a/buildcc/lib/target/src/target/build.cpp b/buildcc/lib/target/src/target/build.cpp index 7d00cd19..7435e7a5 100644 --- a/buildcc/lib/target/src/target/build.cpp +++ b/buildcc/lib/target/src/target/build.cpp @@ -54,19 +54,19 @@ namespace buildcc { void Target::Build() { env::log_trace(name_, __FUNCTION__); - state_.ExpectsUnlock(); - state_.SetLock(); + lock_.ExpectsUnlock(__FUNCTION__); + lock_.Lock(); // PCH state if (!user_.pchs.empty()) { - state_.SetPch(); + state_.PchDetected(); } // Source - Object relation // Source state for (const auto &abs_source : user_.sources) { // Set state - state_.SetSourceState(toolchain_.GetConfig().GetFileExt(abs_source)); + state_.SourceDetected(toolchain_.GetConfig().GetFileExt(abs_source)); // Relate input source with output object compile_object_.AddObjectData(abs_source); diff --git a/buildcc/lib/target/src/target/friend/compile_pch.cpp b/buildcc/lib/target/src/target/friend/compile_pch.cpp index 312b8b7c..83e7cf62 100644 --- a/buildcc/lib/target/src/target/friend/compile_pch.cpp +++ b/buildcc/lib/target/src/target/friend/compile_pch.cpp @@ -64,7 +64,7 @@ namespace buildcc::internal { // PUBLIC void CompilePch::CacheCompileCommand() { - source_path_ = ConstructSourcePath(target_.GetState().contains_cpp); + source_path_ = ConstructSourcePath(target_.GetState().ContainsCpp()); command_ = ConstructCompileCommand(); } @@ -138,12 +138,12 @@ fs::path CompilePch::ConstructObjectPath() const { } std::string CompilePch::ConstructCompileCommand() const { - std::string compiler = target_.GetState().contains_cpp + std::string compiler = target_.GetState().ContainsCpp() ? target_.GetToolchain().GetCppCompiler() : target_.GetToolchain().GetCCompiler(); compiler = fmt::format("{}", fs::path(compiler)); const FileExt file_ext_type = - target_.GetState().contains_cpp ? FileExt::Cpp : FileExt::C; + target_.GetState().ContainsCpp() ? FileExt::Cpp : FileExt::C; const std::string compile_flags = target_.SelectCompileFlags(file_ext_type).value_or(""); const std::string pch_compile_path = fmt::format("{}", compile_path_); diff --git a/buildcc/lib/target/src/target/tasks.cpp b/buildcc/lib/target/src/target/tasks.cpp index 94b81ec7..0efb6e54 100644 --- a/buildcc/lib/target/src/target/tasks.cpp +++ b/buildcc/lib/target/src/target/tasks.cpp @@ -173,7 +173,7 @@ void Target::EndTask() { serialization_.UpdateStore(user_); env::assert_throw(serialization_.StoreToFile(), fmt::format("Store failed for {}", GetName())); - state_.build = true; + state_.BuildCompleted(); } catch (...) { SetTaskStateFailure(); } diff --git a/buildcc/lib/target/test/target/test_target_state.cpp b/buildcc/lib/target/test/target/test_target_state.cpp index f3af3363..ec8806c9 100644 --- a/buildcc/lib/target/test/target/test_target_state.cpp +++ b/buildcc/lib/target/test/target/test_target_state.cpp @@ -16,21 +16,21 @@ TEST_GROUP(TargetStateTestGroup) TEST(TargetStateTestGroup, SetSourceState) { buildcc::TargetState target_state; - CHECK_FALSE(target_state.contains_c); - target_state.SetSourceState(buildcc::FileExt::C); - CHECK_TRUE(target_state.contains_c); + CHECK_FALSE(target_state.ContainsC()); + target_state.SourceDetected(buildcc::FileExt::C); + CHECK_TRUE(target_state.ContainsC()); - CHECK_FALSE(target_state.contains_cpp); - target_state.SetSourceState(buildcc::FileExt::Cpp); - CHECK_TRUE(target_state.contains_cpp); + CHECK_FALSE(target_state.ContainsCpp()); + target_state.SourceDetected(buildcc::FileExt::Cpp); + CHECK_TRUE(target_state.ContainsCpp()); - CHECK_FALSE(target_state.contains_asm); - target_state.SetSourceState(buildcc::FileExt::Asm); - CHECK_TRUE(target_state.contains_asm); + CHECK_FALSE(target_state.ContainsAsm()); + target_state.SourceDetected(buildcc::FileExt::Asm); + CHECK_TRUE(target_state.ContainsAsm()); // Ignored - target_state.SetSourceState(buildcc::FileExt::Header); - target_state.SetSourceState(buildcc::FileExt::Invalid); + target_state.SourceDetected(buildcc::FileExt::Header); + target_state.SourceDetected(buildcc::FileExt::Invalid); } int main(int ac, char **av) { From f8f642708c81bcc28701733d8e43dc7ab1113128 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 16 Mar 2022 20:18:50 -0700 Subject: [PATCH 06/35] Toolchain flags api (#197) --- bootstrap/src/build_buildcc.cpp | 2 + .../lib/args/test/test_persistent_storage.cpp | 4 +- .../lib/target/cmake/common_target_src.cmake | 6 +- .../lib/target/include/target/api/deps_api.h | 1 - .../target/include/target/api/include_api.h | 1 - .../lib/target/include/target/api/lib_api.h | 1 - .../lib/target/include/target/api/pch_api.h | 1 - .../target/include/target/api/source_api.h | 1 - .../lib/target/include/target/api/sync_api.h | 1 - .../target/include/target/api/target_getter.h | 7 ++ .../include/target/api/target_info_getter.h | 15 +--- buildcc/lib/target/include/target/generator.h | 1 + buildcc/lib/target/include/target/target.h | 12 ++- .../lib/target/include/target/target_info.h | 14 +-- buildcc/lib/target/src/api/flag_api.cpp | 46 +++++++++- buildcc/lib/target/src/api/target_getter.cpp | 19 ++++ .../lib/target/src/api/target_info_getter.cpp | 83 ----------------- .../target/src/target_info/target_info.cpp | 52 +++++++++++ buildcc/lib/target/test/target/CMakeLists.txt | 9 ++ .../target/test/target/test_base_target.cpp | 4 +- .../test/target/test_target_external_lib.cpp | 4 +- .../target/test_target_failure_states.cpp | 4 +- .../target/test/target/test_target_flags.cpp | 4 +- .../test/target/test_target_include_dir.cpp | 4 +- .../test/target/test_target_lib_dep.cpp | 4 +- .../target/test/target/test_target_lock.cpp | 4 +- .../target/test/target/test_target_pch.cpp | 4 +- .../target/test/target/test_target_source.cpp | 4 +- .../target/test_target_source_out_of_root.cpp | 4 +- .../target/test/target/test_target_sync.cpp | 4 +- .../test/target/test_target_user_deps.cpp | 4 +- .../test/target/test_toolchain_flag_api.cpp | 89 +++++++++++++++++++ buildcc/lib/toolchain/CMakeLists.txt | 13 ++- .../include/toolchain}/api/flag_api.h | 19 +++- .../include/toolchain}/common/function_lock.h | 10 ++- .../toolchain/include/toolchain/toolchain.h | 37 ++++++-- .../lib/toolchain/src/toolchain/toolchain.cpp | 25 ++++++ docs/source/user_api/toolchain_utils.rst | 5 ++ 38 files changed, 362 insertions(+), 160 deletions(-) create mode 100644 buildcc/lib/target/src/target_info/target_info.cpp create mode 100644 buildcc/lib/target/test/target/test_toolchain_flag_api.cpp rename buildcc/lib/{target/include/target => toolchain/include/toolchain}/api/flag_api.h (63%) rename buildcc/lib/{target/include/target => toolchain/include/toolchain}/common/function_lock.h (84%) create mode 100644 buildcc/lib/toolchain/src/toolchain/toolchain.cpp diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index 70765e9d..0d367c3d 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -63,6 +63,7 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, // TOOLCHAIN target.GlobSources("lib/toolchain/src/api"); target.GlobSources("lib/toolchain/src/common"); + target.GlobSources("lib/toolchain/src/toolchain"); target.AddIncludeDir("lib/toolchain/include"); target.GlobHeaders("lib/toolchain/include/toolchain"); target.GlobHeaders("lib/toolchain/include/toolchain/api"); @@ -72,6 +73,7 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, target.GlobSources("lib/target/src/common"); target.GlobSources("lib/target/src/generator"); target.GlobSources("lib/target/src/api"); + target.GlobSources("lib/target/src/target_info"); target.GlobSources("lib/target/src/target"); target.GlobSources("lib/target/src/target/friend"); diff --git a/buildcc/lib/args/test/test_persistent_storage.cpp b/buildcc/lib/args/test/test_persistent_storage.cpp index 16079c4e..97cc167a 100644 --- a/buildcc/lib/args/test/test_persistent_storage.cpp +++ b/buildcc/lib/args/test/test_persistent_storage.cpp @@ -16,8 +16,8 @@ TEST_GROUP(PersistentStorageTestGroup) }; // clang-format on -buildcc::BaseToolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); +static buildcc::BaseToolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); TEST(PersistentStorageTestGroup, BasicUsage) { buildcc::PersistentStorage persistent; diff --git a/buildcc/lib/target/cmake/common_target_src.cmake b/buildcc/lib/target/cmake/common_target_src.cmake index 6f2bb771..76564d86 100644 --- a/buildcc/lib/target/cmake/common_target_src.cmake +++ b/buildcc/lib/target/cmake/common_target_src.cmake @@ -23,7 +23,6 @@ set(COMMON_TARGET_SRCS include/target/api/include_api.h include/target/api/lib_api.h include/target/api/pch_api.h - include/target/api/flag_api.h include/target/api/deps_api.h src/api/sync_api.cpp @@ -38,6 +37,10 @@ set(COMMON_TARGET_SRCS src/generator/generator.cpp include/target/generator.h + # Target Info + src/target_info/target_info.cpp + include/target/target_info.h + # Target friend src/target/friend/compile_pch.cpp src/target/friend/compile_object.cpp @@ -49,6 +52,5 @@ set(COMMON_TARGET_SRCS # Target src/target/target.cpp src/target/build.cpp - include/target/target_info.h include/target/target.h ) diff --git a/buildcc/lib/target/include/target/api/deps_api.h b/buildcc/lib/target/include/target/api/deps_api.h index 16ba7707..0e0c3e61 100644 --- a/buildcc/lib/target/include/target/api/deps_api.h +++ b/buildcc/lib/target/include/target/api/deps_api.h @@ -25,7 +25,6 @@ namespace buildcc::internal { // Requires // - TargetStorer -// - TargetState // - TargetEnv template class DepsApi { public: diff --git a/buildcc/lib/target/include/target/api/include_api.h b/buildcc/lib/target/include/target/api/include_api.h index 94307e81..1c98ab54 100644 --- a/buildcc/lib/target/include/target/api/include_api.h +++ b/buildcc/lib/target/include/target/api/include_api.h @@ -25,7 +25,6 @@ namespace buildcc::internal { // Requires // - TargetStorer -// - TargetState // - TargetConfig // - TargetEnv template class IncludeApi { diff --git a/buildcc/lib/target/include/target/api/lib_api.h b/buildcc/lib/target/include/target/api/lib_api.h index 834ec3e7..ecfa44cf 100644 --- a/buildcc/lib/target/include/target/api/lib_api.h +++ b/buildcc/lib/target/include/target/api/lib_api.h @@ -32,7 +32,6 @@ namespace buildcc::internal { // Requires // - TargetStorer -// - TargetState // - TargetEnv // T::GetTargetPath template class LibApi { diff --git a/buildcc/lib/target/include/target/api/pch_api.h b/buildcc/lib/target/include/target/api/pch_api.h index 0955ff95..42c53d7a 100644 --- a/buildcc/lib/target/include/target/api/pch_api.h +++ b/buildcc/lib/target/include/target/api/pch_api.h @@ -25,7 +25,6 @@ namespace buildcc::internal { // Requires // - TargetStorer -// - TargetState // - TargetConfig // - TargetEnv template class PchApi { diff --git a/buildcc/lib/target/include/target/api/source_api.h b/buildcc/lib/target/include/target/api/source_api.h index f90c2118..35bd6cd2 100644 --- a/buildcc/lib/target/include/target/api/source_api.h +++ b/buildcc/lib/target/include/target/api/source_api.h @@ -25,7 +25,6 @@ namespace buildcc::internal { // Requires // - TargetStorer -// - TargetState // - TargetConfig // - TargetEnv template class SourceApi { diff --git a/buildcc/lib/target/include/target/api/sync_api.h b/buildcc/lib/target/include/target/api/sync_api.h index 37910d67..c374caab 100644 --- a/buildcc/lib/target/include/target/api/sync_api.h +++ b/buildcc/lib/target/include/target/api/sync_api.h @@ -43,7 +43,6 @@ enum class SyncOption { // Requires // - TargetStorer -// - TargetState template class SyncApi { public: /** diff --git a/buildcc/lib/target/include/target/api/target_getter.h b/buildcc/lib/target/include/target/api/target_getter.h index fc1da53f..3c8f0f88 100644 --- a/buildcc/lib/target/include/target/api/target_getter.h +++ b/buildcc/lib/target/include/target/api/target_getter.h @@ -24,6 +24,8 @@ #include "toolchain/toolchain.h" +#include "target/common/target_state.h" + #include "taskflow/taskflow.hpp" namespace fs = std::filesystem; @@ -32,6 +34,11 @@ namespace buildcc::internal { template class TargetGetter { public: + // Target State + const TargetState &GetState() const; + bool IsBuilt() const; + bool IsLocked() const; + const std::string &GetName() const; const Toolchain &GetToolchain() const; TargetType GetType() const; diff --git a/buildcc/lib/target/include/target/api/target_info_getter.h b/buildcc/lib/target/include/target/api/target_info_getter.h index bf912122..1640c19c 100644 --- a/buildcc/lib/target/include/target/api/target_info_getter.h +++ b/buildcc/lib/target/include/target/api/target_info_getter.h @@ -26,16 +26,10 @@ namespace buildcc::internal { // Requires // - TargetStorer -// - TargetState // - TargetEnv // - TargetConfig template class TargetInfoGetter { public: - // Target State - const TargetState &GetState() const; - bool IsBuilt() const; - bool IsLocked() const; - // Target Env const fs::path &GetTargetRootDir() const; const fs::path &GetTargetBuildDir() const; @@ -51,14 +45,7 @@ template class TargetInfoGetter { const std::vector &GetExternalLibDeps() const; const fs_unordered_set &GetIncludeDirs() const; const fs_unordered_set &GetLibDirs() const; - const std::unordered_set &GetPreprocessorFlags() const; - const std::unordered_set &GetCommonCompileFlags() const; - const std::unordered_set &GetPchCompileFlags() const; - const std::unordered_set &GetPchObjectFlags() const; - const std::unordered_set &GetAsmCompileFlags() const; - const std::unordered_set &GetCCompileFlags() const; - const std::unordered_set &GetCppCompileFlags() const; - const std::unordered_set &GetLinkFlags() const; + const fs_unordered_set &GetCompileDependencies() const; const fs_unordered_set &GetLinkDependencies() const; }; diff --git a/buildcc/lib/target/include/target/generator.h b/buildcc/lib/target/include/target/generator.h index fe013450..74f9612a 100644 --- a/buildcc/lib/target/include/target/generator.h +++ b/buildcc/lib/target/include/target/generator.h @@ -39,6 +39,7 @@ namespace buildcc { +// TODO, Make this private struct UserGeneratorSchema : public internal::GeneratorSchema { fs_unordered_set inputs; }; diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index ed72277f..adea83ed 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -140,22 +140,20 @@ class Target : public internal::BuilderInterface, std::string name_; TargetType type_; internal::TargetSerialization serialization_; - - // Friend classes internal::CompilePch compile_pch_; internal::CompileObject compile_object_; internal::LinkTarget link_target_; + // + TargetState state_; + env::Command command_; + tf::Taskflow tf_; + // Task states tf::Task target_start_task_; tf::Task target_end_task_; - std::mutex task_state_mutex_; env::TaskState task_state_{env::TaskState::SUCCESS}; - - // - env::Command command_; - tf::Taskflow tf_; }; typedef Target BaseTarget; diff --git a/buildcc/lib/target/include/target/target_info.h b/buildcc/lib/target/include/target/target_info.h index 98115a51..0b85bac2 100644 --- a/buildcc/lib/target/include/target/target_info.h +++ b/buildcc/lib/target/include/target/target_info.h @@ -21,13 +21,10 @@ #include "toolchain/toolchain.h" -#include "target/common/function_lock.h" #include "target/common/target_config.h" #include "target/common/target_env.h" -#include "target/common/target_state.h" #include "target/api/deps_api.h" -#include "target/api/flag_api.h" #include "target/api/include_api.h" #include "target/api/lib_api.h" #include "target/api/pch_api.h" @@ -39,6 +36,7 @@ namespace buildcc { +// TODO, Make this private struct UserTargetSchema : public internal::TargetSchema { fs_unordered_set sources; fs_unordered_set headers; @@ -65,7 +63,9 @@ class TargetInfo : public internal::SourceApi, public: TargetInfo(const BaseToolchain &toolchain, const TargetEnv &env, const TargetConfig &config = TargetConfig()) - : toolchain_(toolchain), env_(env), config_(config) {} + : toolchain_(toolchain), env_(env), config_(config) { + Initialize(); + } private: // Inputs @@ -87,10 +87,12 @@ class TargetInfo : public internal::SourceApi, TargetEnv env_; TargetConfig config_; + // UserTargetSchema user_; - FunctionLock lock_; - TargetState state_; + +private: + void Initialize(); }; typedef TargetInfo BaseTargetInfo; diff --git a/buildcc/lib/target/src/api/flag_api.cpp b/buildcc/lib/target/src/api/flag_api.cpp index 856b46bb..a7535250 100644 --- a/buildcc/lib/target/src/api/flag_api.cpp +++ b/buildcc/lib/target/src/api/flag_api.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "target/api/flag_api.h" +#include "toolchain/api/flag_api.h" #include "target/target_info.h" @@ -76,6 +76,50 @@ template void FlagApi::AddLinkFlag(const std::string &flag) { t.user_.link_flags.insert(flag); } +template +const std::unordered_set & +FlagApi::GetPreprocessorFlags() const { + const T &t = static_cast(*this); + return t.user_.preprocessor_flags; +} +template +const std::unordered_set & +FlagApi::GetCommonCompileFlags() const { + const T &t = static_cast(*this); + return t.user_.common_compile_flags; +} +template +const std::unordered_set &FlagApi::GetPchCompileFlags() const { + const T &t = static_cast(*this); + return t.user_.pch_compile_flags; +} +template +const std::unordered_set &FlagApi::GetPchObjectFlags() const { + const T &t = static_cast(*this); + return t.user_.pch_object_flags; +} +template +const std::unordered_set &FlagApi::GetAsmCompileFlags() const { + const T &t = static_cast(*this); + return t.user_.asm_compile_flags; +} +template +const std::unordered_set &FlagApi::GetCCompileFlags() const { + const T &t = static_cast(*this); + return t.user_.c_compile_flags; +} +template +const std::unordered_set &FlagApi::GetCppCompileFlags() const { + const T &t = static_cast(*this); + return t.user_.cpp_compile_flags; +} +template +const std::unordered_set &FlagApi::GetLinkFlags() const { + const T &t = static_cast(*this); + return t.user_.link_flags; +} + template class FlagApi; +template class FlagApi; } // namespace buildcc::internal diff --git a/buildcc/lib/target/src/api/target_getter.cpp b/buildcc/lib/target/src/api/target_getter.cpp index 0c490c25..b5c45fd9 100644 --- a/buildcc/lib/target/src/api/target_getter.cpp +++ b/buildcc/lib/target/src/api/target_getter.cpp @@ -20,6 +20,25 @@ namespace buildcc::internal { +// Target State +template const TargetState &TargetGetter::GetState() const { + const T &t = static_cast(*this); + + return t.state_; +} + +template bool TargetGetter::IsBuilt() const { + const T &t = static_cast(*this); + + return t.state_.IsBuilt(); +} + +template bool TargetGetter::IsLocked() const { + const T &t = static_cast(*this); + + return t.lock_.IsLocked(); +} + template const fs::path &TargetGetter::GetBinaryPath() const { const T &t = static_cast(*this); diff --git a/buildcc/lib/target/src/api/target_info_getter.cpp b/buildcc/lib/target/src/api/target_info_getter.cpp index 7efdc88a..75c0d28b 100644 --- a/buildcc/lib/target/src/api/target_info_getter.cpp +++ b/buildcc/lib/target/src/api/target_info_getter.cpp @@ -20,25 +20,6 @@ namespace buildcc::internal { -// Target State -template const TargetState &TargetInfoGetter::GetState() const { - const T &t = static_cast(*this); - - return t.state_; -} - -template bool TargetInfoGetter::IsBuilt() const { - const T &t = static_cast(*this); - - return t.state_.IsBuilt(); -} - -template bool TargetInfoGetter::IsLocked() const { - const T &t = static_cast(*this); - - return t.lock_.IsLocked(); -} - // Target Env template const fs::path &TargetInfoGetter::GetTargetRootDir() const { @@ -113,70 +94,6 @@ const fs_unordered_set &TargetInfoGetter::GetLibDirs() const { return t.user_.lib_dirs; } -template -const std::unordered_set & -TargetInfoGetter::GetPreprocessorFlags() const { - const T &t = static_cast(*this); - - return t.user_.preprocessor_flags; -} - -template -const std::unordered_set & -TargetInfoGetter::GetCommonCompileFlags() const { - const T &t = static_cast(*this); - - return t.user_.common_compile_flags; -} - -template -const std::unordered_set & -TargetInfoGetter::GetPchCompileFlags() const { - const T &t = static_cast(*this); - - return t.user_.pch_compile_flags; -} - -template -const std::unordered_set & -TargetInfoGetter::GetPchObjectFlags() const { - const T &t = static_cast(*this); - - return t.user_.pch_object_flags; -} - -template -const std::unordered_set & -TargetInfoGetter::GetAsmCompileFlags() const { - const T &t = static_cast(*this); - - return t.user_.asm_compile_flags; -} - -template -const std::unordered_set & -TargetInfoGetter::GetCCompileFlags() const { - const T &t = static_cast(*this); - - return t.user_.c_compile_flags; -} - -template -const std::unordered_set & -TargetInfoGetter::GetCppCompileFlags() const { - const T &t = static_cast(*this); - - return t.user_.cpp_compile_flags; -} - -template -const std::unordered_set & -TargetInfoGetter::GetLinkFlags() const { - const T &t = static_cast(*this); - - return t.user_.link_flags; -} - template const fs_unordered_set &TargetInfoGetter::GetCompileDependencies() const { const T &t = static_cast(*this); diff --git a/buildcc/lib/target/src/target_info/target_info.cpp b/buildcc/lib/target/src/target_info/target_info.cpp new file mode 100644 index 00000000..34dec92f --- /dev/null +++ b/buildcc/lib/target/src/target_info/target_info.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "target/target_info.h" + +namespace buildcc { + +// PRIVATE + +void TargetInfo::Initialize() { + toolchain_.GetLockInfo().ExpectsLock("TargetInfo with Toolchain"); + + std::for_each(toolchain_.GetPreprocessorFlags().begin(), + toolchain_.GetPreprocessorFlags().end(), + [&](const std::string &flag) { AddPreprocessorFlag(flag); }); + std::for_each(toolchain_.GetCommonCompileFlags().begin(), + toolchain_.GetCommonCompileFlags().end(), + [&](const std::string &flag) { AddCommonCompileFlag(flag); }); + std::for_each(toolchain_.GetPchCompileFlags().begin(), + toolchain_.GetPchCompileFlags().end(), + [&](const std::string &flag) { AddPchCompileFlag(flag); }); + std::for_each(toolchain_.GetPchObjectFlags().begin(), + toolchain_.GetPchObjectFlags().end(), + [&](const std::string &flag) { AddPchObjectFlag(flag); }); + std::for_each(toolchain_.GetAsmCompileFlags().begin(), + toolchain_.GetAsmCompileFlags().end(), + [&](const std::string &flag) { AddAsmCompileFlag(flag); }); + std::for_each(toolchain_.GetCCompileFlags().begin(), + toolchain_.GetCCompileFlags().end(), + [&](const std::string &flag) { AddCCompileFlag(flag); }); + std::for_each(toolchain_.GetCppCompileFlags().begin(), + toolchain_.GetCppCompileFlags().end(), + [&](const std::string &flag) { AddCppCompileFlag(flag); }); + std::for_each(toolchain_.GetLinkFlags().begin(), + toolchain_.GetLinkFlags().end(), + [&](const std::string &flag) { AddLinkFlag(flag); }); +} + +} // namespace buildcc diff --git a/buildcc/lib/target/test/target/CMakeLists.txt b/buildcc/lib/target/test/target/CMakeLists.txt index 83d29bbe..44acb230 100644 --- a/buildcc/lib/target/test/target/CMakeLists.txt +++ b/buildcc/lib/target/test/target/CMakeLists.txt @@ -8,6 +8,15 @@ target_link_libraries(target_interface INTERFACE mock_target ) +# Toolchain + +add_executable(test_toolchain_flag_api + test_toolchain_flag_api.cpp +) +target_link_libraries(test_toolchain_flag_api PRIVATE target_interface) + +add_test(NAME test_toolchain_flag_api COMMAND test_toolchain_flag_api) + # Interfaces add_executable(test_builder_interface test_builder_interface.cpp diff --git a/buildcc/lib/target/test/target/test_base_target.cpp b/buildcc/lib/target/test/target/test_base_target.cpp index 582f1a8e..4f8d7639 100644 --- a/buildcc/lib/target/test/target/test_base_target.cpp +++ b/buildcc/lib/target/test/target/test_base_target.cpp @@ -21,8 +21,8 @@ TEST_GROUP(TargetBaseTestGroup) } }; // clang-format on -static const buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", - "gcc", "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); TEST(TargetBaseTestGroup, InvalidTargetType) { constexpr const char *const INVALID_NAME = "Invalid.random"; diff --git a/buildcc/lib/target/test/target/test_target_external_lib.cpp b/buildcc/lib/target/test/target/test_target_external_lib.cpp index 7e12128e..ec6bfcc5 100644 --- a/buildcc/lib/target/test/target/test_target_external_lib.cpp +++ b/buildcc/lib/target/test/target/test_target_external_lib.cpp @@ -27,8 +27,8 @@ TEST_GROUP(TargetTestExternalLib) }; // clang-format on -static const buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", - "gcc", "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); static const fs::path intermediate_path = fs::path(BUILD_TARGET_EXTERNAL_LIB_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_failure_states.cpp b/buildcc/lib/target/test/target/test_target_failure_states.cpp index bfe00ed9..5f64f4d9 100644 --- a/buildcc/lib/target/test/target/test_target_failure_states.cpp +++ b/buildcc/lib/target/test/target/test_target_failure_states.cpp @@ -25,8 +25,8 @@ TEST_GROUP(TargetTestFailureStates) }; // clang-format on -buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); TEST(TargetTestFailureStates, StartTaskEnvFailure) { buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE); diff --git a/buildcc/lib/target/test/target/test_target_flags.cpp b/buildcc/lib/target/test/target/test_target_flags.cpp index 087dab6f..54434648 100644 --- a/buildcc/lib/target/test/target/test_target_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_flags.cpp @@ -21,8 +21,8 @@ // Constants -static const buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", - "gcc", "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); // ------------- PREPROCESSOR FLAGS --------------- diff --git a/buildcc/lib/target/test/target/test_target_include_dir.cpp b/buildcc/lib/target/test/target/test_target_include_dir.cpp index 323a6935..e3a23dc7 100644 --- a/buildcc/lib/target/test/target/test_target_include_dir.cpp +++ b/buildcc/lib/target/test/target/test_target_include_dir.cpp @@ -26,8 +26,8 @@ TEST_GROUP(TargetTestIncludeDirGroup) }; // clang-format on -static const buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", - "gcc", "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); static const fs::path target_include_dir_intermediate_path = fs::path(BUILD_TARGET_INCLUDE_DIR_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_lib_dep.cpp b/buildcc/lib/target/test/target/test_target_lib_dep.cpp index a5cbda68..9b71856a 100644 --- a/buildcc/lib/target/test/target/test_target_lib_dep.cpp +++ b/buildcc/lib/target/test/target/test_target_lib_dep.cpp @@ -30,8 +30,8 @@ TEST_GROUP(TargetTestLibDep) }; // clang-format on -static const buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", - "gcc", "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); static const fs::path intermediate_path = fs::path(BUILD_TARGET_LIB_DEP_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_lock.cpp b/buildcc/lib/target/test/target/test_target_lock.cpp index 944e5b10..5bd6b2c8 100644 --- a/buildcc/lib/target/test/target/test_target_lock.cpp +++ b/buildcc/lib/target/test/target/test_target_lock.cpp @@ -25,8 +25,8 @@ TEST_GROUP(TargetTestLock) }; // clang-format on -static const buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", - "gcc", "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); TEST(TargetTestLock, LockState) { constexpr const char *const NAME = "LockState.exe"; diff --git a/buildcc/lib/target/test/target/test_target_pch.cpp b/buildcc/lib/target/test/target/test_target_pch.cpp index fcfc3653..38833475 100644 --- a/buildcc/lib/target/test/target/test_target_pch.cpp +++ b/buildcc/lib/target/test/target/test_target_pch.cpp @@ -30,8 +30,8 @@ TEST_GROUP(TargetPchTestGroup) }; // clang-format on -static const buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", - "gcc", "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); TEST(TargetPchTestGroup, Target_AddPch) { constexpr const char *const NAME = "AddPch.exe"; diff --git a/buildcc/lib/target/test/target/test_target_source.cpp b/buildcc/lib/target/test/target/test_target_source.cpp index 45ed348f..389dda74 100644 --- a/buildcc/lib/target/test/target/test_target_source.cpp +++ b/buildcc/lib/target/test/target/test_target_source.cpp @@ -27,8 +27,8 @@ TEST_GROUP(TargetTestSourceGroup) }; // clang-format on -static const buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", - "gcc", "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); static const fs::path target_source_intermediate_path = fs::path(BUILD_TARGET_SOURCE_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp b/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp index e2155224..478b104e 100644 --- a/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp +++ b/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp @@ -26,8 +26,8 @@ TEST_GROUP(TargetTestSourceOutOfRootGroup) }; // clang-format on -static const buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", - "gcc", "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); static const fs::path target_source_intermediate_path = fs::path(BUILD_TARGET_SOURCE_OUT_OF_ROOT_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_sync.cpp b/buildcc/lib/target/test/target/test_target_sync.cpp index 9bceb565..2b813406 100644 --- a/buildcc/lib/target/test/target/test_target_sync.cpp +++ b/buildcc/lib/target/test/target/test_target_sync.cpp @@ -19,8 +19,8 @@ TEST_GROUP(TargetTestSyncGroup) }; // clang-format on -buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ldd"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ldd"); TEST(TargetTestSyncGroup, CopyByConstRef) { buildcc::BaseTarget srcTarget("srcTarget", buildcc::TargetType::Executable, diff --git a/buildcc/lib/target/test/target/test_target_user_deps.cpp b/buildcc/lib/target/test/target/test_target_user_deps.cpp index 8af6c4f0..237da156 100644 --- a/buildcc/lib/target/test/target/test_target_user_deps.cpp +++ b/buildcc/lib/target/test/target/test_target_user_deps.cpp @@ -27,8 +27,8 @@ TEST_GROUP(TargetTestUserDepsGroup) }; // clang-format on -static const buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", - "gcc", "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); static const fs::path target_source_intermediate_path = fs::path(BUILD_TARGET_USER_DEPS_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp new file mode 100644 index 00000000..3d698891 --- /dev/null +++ b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp @@ -0,0 +1,89 @@ +#include "toolchain/toolchain.h" + +#include "target/target_info.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" + +// clang-format off +TEST_GROUP(ToolchainFlagApiTestGroup) +{ +}; +// clang-format on + +TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Lock) { + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld"); + CHECK_THROWS(std::exception, toolchain.AddPreprocessorFlag("-preprocessor")); + CHECK_THROWS(std::exception, toolchain.AddAsmCompileFlag("-asm")); + CHECK_THROWS(std::exception, toolchain.AddPchCompileFlag("-pchcompile")); + CHECK_THROWS(std::exception, toolchain.AddPchObjectFlag("-pchobject")); + CHECK_THROWS(std::exception, toolchain.AddCommonCompileFlag("-common")); + CHECK_THROWS(std::exception, toolchain.AddCCompileFlag("-c")); + CHECK_THROWS(std::exception, toolchain.AddCppCompileFlag("-cpp")); + CHECK_THROWS(std::exception, toolchain.AddLinkFlag("-link")); +} + +TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Unlock) { + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld", false); + toolchain.AddPreprocessorFlag("-preprocessor"); + toolchain.AddAsmCompileFlag("-asm"); + toolchain.AddPchCompileFlag("-pchcompile"); + toolchain.AddPchObjectFlag("-pchobject"); + toolchain.AddCommonCompileFlag("-common"); + toolchain.AddCCompileFlag("-c"); + toolchain.AddCppCompileFlag("-cpp"); + toolchain.AddLinkFlag("-link"); + CHECK_FALSE(toolchain.GetLockInfo().IsLocked()); + + toolchain.Lock(); + CHECK_TRUE(toolchain.GetLockInfo().IsLocked()); + + CHECK_EQUAL(toolchain.GetPreprocessorFlags().size(), 1); + CHECK_EQUAL(toolchain.GetAsmCompileFlags().size(), 1); + CHECK_EQUAL(toolchain.GetPchCompileFlags().size(), 1); + CHECK_EQUAL(toolchain.GetPchObjectFlags().size(), 1); + CHECK_EQUAL(toolchain.GetCommonCompileFlags().size(), 1); + CHECK_EQUAL(toolchain.GetCCompileFlags().size(), 1); + CHECK_EQUAL(toolchain.GetCppCompileFlags().size(), 1); + CHECK_EQUAL(toolchain.GetLinkFlags().size(), 1); +} + +TEST(ToolchainFlagApiTestGroup, BasicTargetTest) { + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", + "g++", "ar", "ld", false); + + toolchain.AddPreprocessorFlag("-preprocessor"); + toolchain.AddAsmCompileFlag("-asm"); + toolchain.AddPchCompileFlag("-pchcompile"); + toolchain.AddPchObjectFlag("-pchobject"); + toolchain.AddCommonCompileFlag("-common"); + toolchain.AddCCompileFlag("-c"); + toolchain.AddCppCompileFlag("-cpp"); + toolchain.AddLinkFlag("-link"); + + CHECK_FALSE(toolchain.GetLockInfo().IsLocked()); + { CHECK_THROWS(std::exception, (buildcc::TargetInfo(toolchain, ""))); } + + toolchain.Lock(); + CHECK_TRUE(toolchain.GetLockInfo().IsLocked()); + { + buildcc::TargetInfo targetinfo(toolchain, ""); + CHECK_EQUAL(targetinfo.GetPreprocessorFlags().size(), 1); + CHECK_EQUAL(targetinfo.GetAsmCompileFlags().size(), 1); + CHECK_EQUAL(targetinfo.GetPchCompileFlags().size(), 1); + CHECK_EQUAL(targetinfo.GetPchObjectFlags().size(), 1); + CHECK_EQUAL(targetinfo.GetCommonCompileFlags().size(), 1); + CHECK_EQUAL(targetinfo.GetCCompileFlags().size(), 1); + CHECK_EQUAL(targetinfo.GetCppCompileFlags().size(), 1); + CHECK_EQUAL(targetinfo.GetLinkFlags().size(), 1); + } +} + +int main(int ac, char **av) { + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/lib/toolchain/CMakeLists.txt b/buildcc/lib/toolchain/CMakeLists.txt index 6d8252a3..91570b7d 100644 --- a/buildcc/lib/toolchain/CMakeLists.txt +++ b/buildcc/lib/toolchain/CMakeLists.txt @@ -1,10 +1,15 @@ set(TOOLCHAIN_SRCS - include/toolchain/toolchain.h - - include/toolchain/common/file_ext.h - + # COMMON src/common/toolchain_config.cpp include/toolchain/common/toolchain_config.h + include/toolchain/common/file_ext.h + include/toolchain/common/function_lock.h + + # API + include/toolchain/api/flag_api.h + + src/toolchain/toolchain.cpp + include/toolchain/toolchain.h # Features src/api/toolchain_verify.cpp diff --git a/buildcc/lib/target/include/target/api/flag_api.h b/buildcc/lib/toolchain/include/toolchain/api/flag_api.h similarity index 63% rename from buildcc/lib/target/include/target/api/flag_api.h rename to buildcc/lib/toolchain/include/toolchain/api/flag_api.h index a51ae94f..2fb283ba 100644 --- a/buildcc/lib/target/include/target/api/flag_api.h +++ b/buildcc/lib/toolchain/include/toolchain/api/flag_api.h @@ -14,16 +14,17 @@ * limitations under the License. */ -#ifndef TARGET_API_FLAG_API_H_ -#define TARGET_API_FLAG_API_H_ +#ifndef TOOLCHAIN_API_FLAG_API_H_ +#define TOOLCHAIN_API_FLAG_API_H_ #include +#include namespace buildcc::internal { // Requires -// - TargetStorer -// - TargetState +// TargetSchema +// FunctionLock template class FlagApi { public: void AddPreprocessorFlag(const std::string &flag); @@ -34,6 +35,16 @@ template class FlagApi { void AddCCompileFlag(const std::string &flag); void AddCppCompileFlag(const std::string &flag); void AddLinkFlag(const std::string &flag); + + // Getters + const std::unordered_set &GetPreprocessorFlags() const; + const std::unordered_set &GetCommonCompileFlags() const; + const std::unordered_set &GetPchCompileFlags() const; + const std::unordered_set &GetPchObjectFlags() const; + const std::unordered_set &GetAsmCompileFlags() const; + const std::unordered_set &GetCCompileFlags() const; + const std::unordered_set &GetCppCompileFlags() const; + const std::unordered_set &GetLinkFlags() const; }; } // namespace buildcc::internal diff --git a/buildcc/lib/target/include/target/common/function_lock.h b/buildcc/lib/toolchain/include/toolchain/common/function_lock.h similarity index 84% rename from buildcc/lib/target/include/target/common/function_lock.h rename to buildcc/lib/toolchain/include/toolchain/common/function_lock.h index 3f15bddf..246b8ee7 100644 --- a/buildcc/lib/target/include/target/common/function_lock.h +++ b/buildcc/lib/toolchain/include/toolchain/common/function_lock.h @@ -27,13 +27,19 @@ namespace buildcc { class FunctionLock { public: - void Lock() { lock_ = true; } - void Unlock() { lock_ = false; } + FunctionLock(bool initial_value = false) : lock_(initial_value) {} + + void SetLock(bool lock) { lock_ = lock; } + void Lock() { SetLock(true); } + void Unlock() { SetLock(false); } + bool IsLocked() const { return lock_; } + // TODO, Make this better void ExpectsUnlock(std::string_view tag) const { env::assert_fatal(!lock_, fmt::format("Cannot use {} when lock == true", tag)); } + // TODO, Make this better void ExpectsLock(std::string_view tag) const { env::assert_fatal(lock_, fmt::format("Cannot use {} when lock == false", tag)); diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index dec04968..b58bf968 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -21,14 +21,17 @@ #include #include +#include "toolchain/common/function_lock.h" #include "toolchain/common/toolchain_config.h" +#include "toolchain/api/flag_api.h" #include "toolchain/api/toolchain_verify.h" namespace buildcc { // Base toolchain class -class Toolchain : public ToolchainVerify { +class Toolchain : public internal::FlagApi, + public ToolchainVerify { public: enum class Id { Gcc = 0, ///< GCC Toolchain @@ -43,17 +46,19 @@ class Toolchain : public ToolchainVerify { explicit Toolchain(Id id, std::string_view name, std::string_view asm_compiler, std::string_view c_compiler, std::string_view cpp_compiler, std::string_view archiver, - std::string_view linker, + std::string_view linker, bool lock = true, const ToolchainConfig &config = ToolchainConfig()) : id_(id), name_(name), asm_compiler_(asm_compiler), c_compiler_(c_compiler), cpp_compiler_(cpp_compiler), - archiver_(archiver), linker_(linker), config_(config) { - UpdateConfig(config_); + archiver_(archiver), linker_(linker), config_(config), lock_(lock) { + Initialize(); } Toolchain(Toolchain &&toolchain) = default; Toolchain(const Toolchain &toolchain) = delete; + void Lock(); + // Getters Id GetId() const { return id_; } const std::string &GetName() const { return name_; } @@ -63,12 +68,31 @@ class Toolchain : public ToolchainVerify { const std::string &GetArchiver() const { return archiver_; } const std::string &GetLinker() const { return linker_; } + const FunctionLock &GetLockInfo() const { return lock_; } const ToolchainConfig &GetConfig() const { return config_; } +private: + struct UserSchema { + std::unordered_set preprocessor_flags; + std::unordered_set common_compile_flags; + std::unordered_set pch_compile_flags; + std::unordered_set pch_object_flags; + std::unordered_set asm_compile_flags; + std::unordered_set c_compile_flags; + std::unordered_set cpp_compile_flags; + std::unordered_set link_flags; + }; + private: virtual void UpdateConfig(ToolchainConfig &config) { (void)config; } + void Initialize(); private: + friend class internal::FlagApi; + + // TODO, Remove this and have a virtual `Verify` function instead + // Anti-pattern: ToolchainVerify contains GCC and MSVC specific + // implementations in a "Base" toolchain class friend class ToolchainVerify; private: @@ -79,8 +103,11 @@ class Toolchain : public ToolchainVerify { std::string cpp_compiler_; std::string archiver_; std::string linker_; - ToolchainConfig config_; + FunctionLock lock_; + + // + UserSchema user_; }; typedef Toolchain::Id ToolchainId; diff --git a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp new file mode 100644 index 00000000..3a3ae354 --- /dev/null +++ b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp @@ -0,0 +1,25 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "toolchain/toolchain.h" + +namespace buildcc { + +void Toolchain::Initialize() { UpdateConfig(config_); } + +void Toolchain::Lock() { lock_.Lock(); } + +} // namespace buildcc diff --git a/docs/source/user_api/toolchain_utils.rst b/docs/source/user_api/toolchain_utils.rst index 0e812633..8c2dfcd7 100644 --- a/docs/source/user_api/toolchain_utils.rst +++ b/docs/source/user_api/toolchain_utils.rst @@ -8,6 +8,11 @@ file_ext.h .. doxygenenum:: buildcc::FileExt +function_lock.h +----------------- + +.. doxygenclass:: buildcc::FunctionLock + toolchain_config.h -------------------- From cc5ad25e75d0639ab1c3a941dd26f22f493d106b Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 17 Mar 2022 21:04:28 -0700 Subject: [PATCH 07/35] Toolchain cleanup (#198) --- buildcc/lib/args/include/args/args.h | 23 +++-- buildcc/lib/args/src/args.cpp | 22 ++--- buildcc/lib/args/test/test_args.cpp | 72 +++++++-------- buildcc/lib/args/test/test_register.cpp | 14 +-- .../target/include/target/api/target_getter.h | 4 + .../include/target/api/target_info_getter.h | 4 - buildcc/lib/target/include/target/target.h | 11 ++- .../lib/target/include/target/target_info.h | 8 +- buildcc/lib/target/src/api/target_getter.cpp | 7 ++ .../lib/target/src/api/target_info_getter.cpp | 8 -- buildcc/lib/target/src/target/build.cpp | 4 +- buildcc/lib/target/src/target/target.cpp | 2 +- .../target/src/target_info/target_info.cpp | 3 +- .../target/test/target/test_base_target.cpp | 2 +- .../test/target/test_compile_object.cpp | 2 +- .../test/target/test_target_external_lib.cpp | 2 +- .../target/test_target_failure_states.cpp | 2 +- .../target/test/target/test_target_flags.cpp | 2 +- .../test/target/test_target_include_dir.cpp | 2 +- .../test/target/test_target_lib_dep.cpp | 2 +- .../target/test/target/test_target_lock.cpp | 2 +- .../target/test/target/test_target_pch.cpp | 2 +- .../target/test/target/test_target_source.cpp | 2 +- .../target/test_target_source_out_of_root.cpp | 2 +- .../target/test/target/test_target_sync.cpp | 2 +- .../test/target/test_target_user_deps.cpp | 2 +- .../include/toolchain/common/function_lock.h | 12 ++- .../toolchain/include/toolchain/toolchain.h | 89 +++++++++++-------- .../toolchain/src/api/toolchain_verify.cpp | 63 +++++++------ .../toolchain/test/test_toolchain_verify.cpp | 30 +++---- .../include/toolchains/toolchain_gcc.h | 2 +- .../include/toolchains/toolchain_msvc.h | 3 +- docs/source/user_api/toolchain.rst | 2 - docs/source/user_api/toolchain_utils.rst | 7 ++ 34 files changed, 216 insertions(+), 200 deletions(-) diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index b57e2a6a..05311272 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -48,33 +48,32 @@ struct ArgToolchainState { struct ArgToolchain { ArgToolchain(){}; ArgToolchain(ToolchainId initial_id, const std::string &initial_name, - const std::string &initial_asm_compiler, + const ToolchainBinaries &initial_binaries) + : id(initial_id), name(initial_name), binaries(initial_binaries) {} + ArgToolchain(ToolchainId initial_id, const std::string &initial_name, + const std::string &initial_assembler, const std::string &initial_c_compiler, const std::string &initial_cpp_compiler, const std::string &initial_archiver, const std::string &initial_linker) - : id(initial_id), name(initial_name), asm_compiler(initial_asm_compiler), - c_compiler(initial_c_compiler), cpp_compiler(initial_cpp_compiler), - archiver(initial_archiver), linker(initial_linker) {} + : ArgToolchain(initial_id, initial_name, + ToolchainBinaries(initial_assembler, initial_c_compiler, + initial_cpp_compiler, initial_archiver, + initial_linker)) {} /** * @brief Construct a BaseToolchain from the arguments supplied through the * command line information */ + // TODO, Update this for lock and ToolchainConfig BaseToolchain ConstructToolchain() const { - BaseToolchain toolchain(id, name, asm_compiler, c_compiler, cpp_compiler, - archiver, linker); - return toolchain; + return BaseToolchain(id, name, binaries); } ArgToolchainState state; ToolchainId id{ToolchainId::Undefined}; std::string name{""}; - std::string asm_compiler{""}; - std::string c_compiler{""}; - std::string cpp_compiler{""}; - std::string archiver{""}; - std::string linker{""}; + ToolchainBinaries binaries; }; // NOTE, Incomplete without pch_compile_command diff --git a/buildcc/lib/args/src/args.cpp b/buildcc/lib/args/src/args.cpp index ad1605b0..9c95eb5c 100644 --- a/buildcc/lib/args/src/args.cpp +++ b/buildcc/lib/args/src/args.cpp @@ -75,7 +75,7 @@ const std::unordered_map kLogLevelMap{ {"critical", buildcc::env::LogLevel::Critical}, }; -const std::unordered_map kToolchainIdMap{ +const std::unordered_map kToolchainIdMap{ {"gcc", buildcc::ToolchainId::Gcc}, {"msvc", buildcc::ToolchainId::Msvc}, {"mingw", buildcc::ToolchainId::MinGW}, @@ -99,16 +99,16 @@ void Args::AddToolchain(const std::string &name, const std::string &description, ->transform(CLI::CheckedTransformer(kToolchainIdMap, CLI::ignore_case)) ->default_val(initial.id); t_user->add_option(kToolchainNameParam, out.name)->default_val(initial.name); - t_user->add_option(kToolchainAsmCompilerParam, out.asm_compiler) - ->default_val(initial.asm_compiler); - t_user->add_option(kToolchainCCompilerParam, out.c_compiler) - ->default_val(initial.c_compiler); - t_user->add_option(kToolchainCppCompilerParam, out.cpp_compiler) - ->default_val(initial.cpp_compiler); - t_user->add_option(kToolchainArchiverParam, out.archiver) - ->default_val(initial.archiver); - t_user->add_option(kToolchainLinkerParam, out.linker) - ->default_val(initial.linker); + t_user->add_option(kToolchainAsmCompilerParam, out.binaries.assembler) + ->default_val(initial.binaries.assembler); + t_user->add_option(kToolchainCCompilerParam, out.binaries.c_compiler) + ->default_val(initial.binaries.c_compiler); + t_user->add_option(kToolchainCppCompilerParam, out.binaries.cpp_compiler) + ->default_val(initial.binaries.cpp_compiler); + t_user->add_option(kToolchainArchiverParam, out.binaries.archiver) + ->default_val(initial.binaries.archiver); + t_user->add_option(kToolchainLinkerParam, out.binaries.linker) + ->default_val(initial.binaries.linker); } void Args::AddTarget(const std::string &name, const std::string &description, diff --git a/buildcc/lib/args/test/test_args.cpp b/buildcc/lib/args/test/test_args.cpp index 7a686577..b52179cf 100644 --- a/buildcc/lib/args/test/test_args.cpp +++ b/buildcc/lib/args/test/test_args.cpp @@ -66,13 +66,13 @@ TEST(ArgsTestGroup, Args_CustomToolchain) { // Toolchain CHECK_TRUE(gcc_toolchain.state.build); CHECK_FALSE(gcc_toolchain.state.test); - CHECK(gcc_toolchain.id == buildcc::Toolchain::Id::Gcc); + CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.asm_compiler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); } TEST(ArgsTestGroup, Args_MultipleCustomToolchain) { @@ -104,24 +104,24 @@ TEST(ArgsTestGroup, Args_MultipleCustomToolchain) { // GCC CHECK_TRUE(gcc_toolchain.state.build); CHECK_FALSE(gcc_toolchain.state.test); - CHECK(gcc_toolchain.id == buildcc::Toolchain::Id::Gcc); + CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.asm_compiler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); // MSVC CHECK_TRUE(msvc_toolchain.state.build); CHECK_TRUE(msvc_toolchain.state.test); - CHECK(msvc_toolchain.id == buildcc::Toolchain::Id::Msvc); + CHECK(msvc_toolchain.id == buildcc::ToolchainId::Msvc); STRCMP_EQUAL(msvc_toolchain.name.c_str(), "msvc"); - STRCMP_EQUAL(msvc_toolchain.asm_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.c_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.cpp_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.archiver.c_str(), "lib"); - STRCMP_EQUAL(msvc_toolchain.linker.c_str(), "link"); + STRCMP_EQUAL(msvc_toolchain.binaries.assembler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.binaries.c_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.binaries.cpp_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.binaries.archiver.c_str(), "lib"); + STRCMP_EQUAL(msvc_toolchain.binaries.linker.c_str(), "link"); } TEST(ArgsTestGroup, Args_DuplicateCustomToolchain) { @@ -165,13 +165,13 @@ TEST(ArgsTestGroup, Args_CustomTarget) { // Toolchain CHECK_TRUE(gcc_toolchain.state.build); CHECK_FALSE(gcc_toolchain.state.test); - CHECK(gcc_toolchain.id == buildcc::Toolchain::Id::Gcc); + CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.asm_compiler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); // Target STRCMP_EQUAL(gcc_target.compile_command.c_str(), @@ -219,13 +219,13 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { // Toolchain CHECK_TRUE(gcc_toolchain.state.build); CHECK_FALSE(gcc_toolchain.state.test); - CHECK(gcc_toolchain.id == buildcc::Toolchain::Id::Gcc); + CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.asm_compiler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); // Target STRCMP_EQUAL(gcc_target.compile_command.c_str(), @@ -240,13 +240,13 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { // Toolchain CHECK_TRUE(msvc_toolchain.state.build); CHECK_TRUE(msvc_toolchain.state.test); - CHECK(msvc_toolchain.id == buildcc::Toolchain::Id::Msvc); + CHECK(msvc_toolchain.id == buildcc::ToolchainId::Msvc); STRCMP_EQUAL(msvc_toolchain.name.c_str(), "msvc"); - STRCMP_EQUAL(msvc_toolchain.asm_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.c_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.cpp_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.archiver.c_str(), "lib"); - STRCMP_EQUAL(msvc_toolchain.linker.c_str(), "link"); + STRCMP_EQUAL(msvc_toolchain.binaries.assembler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.binaries.c_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.binaries.cpp_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.binaries.archiver.c_str(), "lib"); + STRCMP_EQUAL(msvc_toolchain.binaries.linker.c_str(), "link"); // Target STRCMP_EQUAL(msvc_target.compile_command.c_str(), diff --git a/buildcc/lib/args/test/test_register.cpp b/buildcc/lib/args/test/test_register.cpp index 62e4ad38..0ccea4bc 100644 --- a/buildcc/lib/args/test/test_register.cpp +++ b/buildcc/lib/args/test/test_register.cpp @@ -100,7 +100,7 @@ TEST(RegisterTestGroup, Register_Build) { // Make dummy toolchain and target buildcc::env::init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::Toolchain::Id::Gcc, "", "", "", "", "", + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); @@ -148,7 +148,7 @@ TEST(RegisterTestGroup, Register_NoBuildAndDep) { // Make dummy toolchain and target buildcc::env::init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::Toolchain::Id::Gcc, "", "", "", "", "", + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); @@ -232,7 +232,7 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { // Make dummy toolchain and target buildcc::env::init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::Toolchain::Id::Gcc, "", "", "", "", "", + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); @@ -327,7 +327,7 @@ TEST(RegisterTestGroup, Register_DepDuplicate) { // Make dummy toolchain and target buildcc::env::init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::Toolchain::Id::Gcc, "", "", "", "", "", + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); @@ -403,7 +403,7 @@ TEST(RegisterTestGroup, Register_DepCyclic) { // Make dummy toolchain and target buildcc::env::init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::Toolchain::Id::Gcc, "", "", "", "", "", + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); @@ -479,7 +479,7 @@ TEST(RegisterTestGroup, Register_Test) { // Make dummy toolchain and target buildcc::env::init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::Toolchain::Id::Gcc, "", "", "", "", "", + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); @@ -564,7 +564,7 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { // Make dummy toolchain and target buildcc::env::init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::Toolchain::Id::Gcc, "", "", "", "", "", + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); diff --git a/buildcc/lib/target/include/target/api/target_getter.h b/buildcc/lib/target/include/target/api/target_getter.h index 3c8f0f88..3ffdca5e 100644 --- a/buildcc/lib/target/include/target/api/target_getter.h +++ b/buildcc/lib/target/include/target/api/target_getter.h @@ -24,6 +24,7 @@ #include "toolchain/toolchain.h" +#include "target/common/target_config.h" #include "target/common/target_state.h" #include "taskflow/taskflow.hpp" @@ -39,6 +40,9 @@ template class TargetGetter { bool IsBuilt() const; bool IsLocked() const; + // Target Config + const TargetConfig &GetConfig() const; + const std::string &GetName() const; const Toolchain &GetToolchain() const; TargetType GetType() const; diff --git a/buildcc/lib/target/include/target/api/target_info_getter.h b/buildcc/lib/target/include/target/api/target_info_getter.h index 1640c19c..814a8238 100644 --- a/buildcc/lib/target/include/target/api/target_info_getter.h +++ b/buildcc/lib/target/include/target/api/target_info_getter.h @@ -19,7 +19,6 @@ #include "schema/path.h" -#include "target/common/target_config.h" #include "target/common/target_state.h" namespace buildcc::internal { @@ -34,9 +33,6 @@ template class TargetInfoGetter { const fs::path &GetTargetRootDir() const; const fs::path &GetTargetBuildDir() const; - // Target Config - const TargetConfig &GetConfig() const; - // Target Storer const fs_unordered_set &GetSourceFiles() const; const fs_unordered_set &GetHeaderFiles() const; diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index adea83ed..cb9b1049 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -69,12 +69,10 @@ class Target : public internal::BuilderInterface, explicit Target(const std::string &name, TargetType type, const Toolchain &toolchain, const TargetEnv &env, const TargetConfig &config = TargetConfig()) - : TargetInfo( - toolchain, - TargetEnv(env.GetTargetRootDir(), - env.GetTargetBuildDir() / toolchain.GetName() / name), - config), - name_(name), type_(type), + : TargetInfo(toolchain, TargetEnv(env.GetTargetRootDir(), + env.GetTargetBuildDir() / + toolchain.GetName() / name)), + name_(name), type_(type), config_(config), serialization_(env_.GetTargetBuildDir() / fmt::format("{}.bin", name)), compile_pch_(*this), compile_object_(*this), link_target_(*this) { Initialize(); @@ -139,6 +137,7 @@ class Target : public internal::BuilderInterface, private: std::string name_; TargetType type_; + TargetConfig config_; internal::TargetSerialization serialization_; internal::CompilePch compile_pch_; internal::CompileObject compile_object_; diff --git a/buildcc/lib/target/include/target/target_info.h b/buildcc/lib/target/include/target/target_info.h index 0b85bac2..4b9f6746 100644 --- a/buildcc/lib/target/include/target/target_info.h +++ b/buildcc/lib/target/include/target/target_info.h @@ -61,9 +61,8 @@ class TargetInfo : public internal::SourceApi, public internal::SyncApi, public internal::TargetInfoGetter { public: - TargetInfo(const BaseToolchain &toolchain, const TargetEnv &env, - const TargetConfig &config = TargetConfig()) - : toolchain_(toolchain), env_(env), config_(config) { + TargetInfo(const BaseToolchain &toolchain, const TargetEnv &env) + : toolchain_(toolchain), env_(env) { Initialize(); } @@ -85,11 +84,10 @@ class TargetInfo : public internal::SourceApi, protected: const BaseToolchain &toolchain_; TargetEnv env_; - TargetConfig config_; // - UserTargetSchema user_; FunctionLock lock_; + UserTargetSchema user_; private: void Initialize(); diff --git a/buildcc/lib/target/src/api/target_getter.cpp b/buildcc/lib/target/src/api/target_getter.cpp index b5c45fd9..61540bff 100644 --- a/buildcc/lib/target/src/api/target_getter.cpp +++ b/buildcc/lib/target/src/api/target_getter.cpp @@ -33,6 +33,13 @@ template bool TargetGetter::IsBuilt() const { return t.state_.IsBuilt(); } +// Target Config +template const TargetConfig &TargetGetter::GetConfig() const { + const T &t = static_cast(*this); + + return t.config_; +} + template bool TargetGetter::IsLocked() const { const T &t = static_cast(*this); diff --git a/buildcc/lib/target/src/api/target_info_getter.cpp b/buildcc/lib/target/src/api/target_info_getter.cpp index 75c0d28b..7083fa48 100644 --- a/buildcc/lib/target/src/api/target_info_getter.cpp +++ b/buildcc/lib/target/src/api/target_info_getter.cpp @@ -35,14 +35,6 @@ const fs::path &TargetInfoGetter::GetTargetBuildDir() const { return t.env_.GetTargetBuildDir(); } -// Target Config -template -const TargetConfig &TargetInfoGetter::GetConfig() const { - const T &t = static_cast(*this); - - return t.config_; -} - // Target Storer template const fs_unordered_set &TargetInfoGetter::GetSourceFiles() const { diff --git a/buildcc/lib/target/src/target/build.cpp b/buildcc/lib/target/src/target/build.cpp index 7435e7a5..43a1572e 100644 --- a/buildcc/lib/target/src/target/build.cpp +++ b/buildcc/lib/target/src/target/build.cpp @@ -54,7 +54,7 @@ namespace buildcc { void Target::Build() { env::log_trace(name_, __FUNCTION__); - lock_.ExpectsUnlock(__FUNCTION__); + lock_.ExpectsUnlock("Target::Build"); lock_.Lock(); // PCH state @@ -87,7 +87,7 @@ void Target::Build() { {kLinkFlags, internal::aggregate(GetLinkFlags())}, // Toolchain executables here - {kAsmCompiler, fmt::format("{}", fs::path(toolchain_.GetAsmCompiler()))}, + {kAsmCompiler, fmt::format("{}", fs::path(toolchain_.GetAssembler()))}, {kCCompiler, fmt::format("{}", fs::path(toolchain_.GetCCompiler()))}, {kCppCompiler, fmt::format("{}", fs::path(toolchain_.GetCppCompiler()))}, {kArchiver, fmt::format("{}", fs::path(toolchain_.GetArchiver()))}, diff --git a/buildcc/lib/target/src/target/target.cpp b/buildcc/lib/target/src/target/target.cpp index dd4aedbe..ab5532bd 100644 --- a/buildcc/lib/target/src/target/target.cpp +++ b/buildcc/lib/target/src/target/target.cpp @@ -109,7 +109,7 @@ std::optional Target::SelectCompileFlags(FileExt ext) const { std::optional Target::SelectCompiler(FileExt ext) const { switch (ext) { case FileExt::Asm: - return GetToolchain().GetAsmCompiler(); + return GetToolchain().GetAssembler(); break; case FileExt::C: return GetToolchain().GetCCompiler(); diff --git a/buildcc/lib/target/src/target_info/target_info.cpp b/buildcc/lib/target/src/target_info/target_info.cpp index 34dec92f..c338d9f6 100644 --- a/buildcc/lib/target/src/target_info/target_info.cpp +++ b/buildcc/lib/target/src/target_info/target_info.cpp @@ -21,7 +21,8 @@ namespace buildcc { // PRIVATE void TargetInfo::Initialize() { - toolchain_.GetLockInfo().ExpectsLock("TargetInfo with Toolchain"); + toolchain_.GetLockInfo().ExpectsLock( + "Toolchain should be locked before usage through `Toolchain::Lock`"); std::for_each(toolchain_.GetPreprocessorFlags().begin(), toolchain_.GetPreprocessorFlags().end(), diff --git a/buildcc/lib/target/test/target/test_base_target.cpp b/buildcc/lib/target/test/target/test_base_target.cpp index 4f8d7639..6f772d7d 100644 --- a/buildcc/lib/target/test/target/test_base_target.cpp +++ b/buildcc/lib/target/test/target/test_base_target.cpp @@ -21,7 +21,7 @@ TEST_GROUP(TargetBaseTestGroup) } }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); TEST(TargetBaseTestGroup, InvalidTargetType) { diff --git a/buildcc/lib/target/test/target/test_compile_object.cpp b/buildcc/lib/target/test/target/test_compile_object.cpp index 0284b395..1819509d 100644 --- a/buildcc/lib/target/test/target/test_compile_object.cpp +++ b/buildcc/lib/target/test/target/test_compile_object.cpp @@ -15,7 +15,7 @@ TEST_GROUP(TargetCompileObjectTestGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); TEST(TargetCompileObjectTestGroup, CacheCompileCommand_Invalid) { diff --git a/buildcc/lib/target/test/target/test_target_external_lib.cpp b/buildcc/lib/target/test/target/test_target_external_lib.cpp index ec6bfcc5..6c04a79c 100644 --- a/buildcc/lib/target/test/target/test_target_external_lib.cpp +++ b/buildcc/lib/target/test/target/test_target_external_lib.cpp @@ -27,7 +27,7 @@ TEST_GROUP(TargetTestExternalLib) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); static const fs::path intermediate_path = diff --git a/buildcc/lib/target/test/target/test_target_failure_states.cpp b/buildcc/lib/target/test/target/test_target_failure_states.cpp index 5f64f4d9..20a2aa74 100644 --- a/buildcc/lib/target/test/target/test_target_failure_states.cpp +++ b/buildcc/lib/target/test/target/test_target_failure_states.cpp @@ -25,7 +25,7 @@ TEST_GROUP(TargetTestFailureStates) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); TEST(TargetTestFailureStates, StartTaskEnvFailure) { diff --git a/buildcc/lib/target/test/target/test_target_flags.cpp b/buildcc/lib/target/test/target/test_target_flags.cpp index 54434648..5a177930 100644 --- a/buildcc/lib/target/test/target/test_target_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_flags.cpp @@ -21,7 +21,7 @@ // Constants -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); // ------------- PREPROCESSOR FLAGS --------------- diff --git a/buildcc/lib/target/test/target/test_target_include_dir.cpp b/buildcc/lib/target/test/target/test_target_include_dir.cpp index e3a23dc7..91fa44b4 100644 --- a/buildcc/lib/target/test/target/test_target_include_dir.cpp +++ b/buildcc/lib/target/test/target/test_target_include_dir.cpp @@ -26,7 +26,7 @@ TEST_GROUP(TargetTestIncludeDirGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); static const fs::path target_include_dir_intermediate_path = diff --git a/buildcc/lib/target/test/target/test_target_lib_dep.cpp b/buildcc/lib/target/test/target/test_target_lib_dep.cpp index 9b71856a..5b0815da 100644 --- a/buildcc/lib/target/test/target/test_target_lib_dep.cpp +++ b/buildcc/lib/target/test/target/test_target_lib_dep.cpp @@ -30,7 +30,7 @@ TEST_GROUP(TargetTestLibDep) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); static const fs::path intermediate_path = diff --git a/buildcc/lib/target/test/target/test_target_lock.cpp b/buildcc/lib/target/test/target/test_target_lock.cpp index 5bd6b2c8..3987d2c3 100644 --- a/buildcc/lib/target/test/target/test_target_lock.cpp +++ b/buildcc/lib/target/test/target/test_target_lock.cpp @@ -25,7 +25,7 @@ TEST_GROUP(TargetTestLock) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); TEST(TargetTestLock, LockState) { diff --git a/buildcc/lib/target/test/target/test_target_pch.cpp b/buildcc/lib/target/test/target/test_target_pch.cpp index 38833475..4cfbac1f 100644 --- a/buildcc/lib/target/test/target/test_target_pch.cpp +++ b/buildcc/lib/target/test/target/test_target_pch.cpp @@ -30,7 +30,7 @@ TEST_GROUP(TargetPchTestGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); TEST(TargetPchTestGroup, Target_AddPch) { diff --git a/buildcc/lib/target/test/target/test_target_source.cpp b/buildcc/lib/target/test/target/test_target_source.cpp index 389dda74..58c9f2d2 100644 --- a/buildcc/lib/target/test/target/test_target_source.cpp +++ b/buildcc/lib/target/test/target/test_target_source.cpp @@ -27,7 +27,7 @@ TEST_GROUP(TargetTestSourceGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); static const fs::path target_source_intermediate_path = diff --git a/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp b/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp index 478b104e..6491950d 100644 --- a/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp +++ b/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp @@ -26,7 +26,7 @@ TEST_GROUP(TargetTestSourceOutOfRootGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); static const fs::path target_source_intermediate_path = diff --git a/buildcc/lib/target/test/target/test_target_sync.cpp b/buildcc/lib/target/test/target/test_target_sync.cpp index 2b813406..cbb55d3e 100644 --- a/buildcc/lib/target/test/target/test_target_sync.cpp +++ b/buildcc/lib/target/test/target/test_target_sync.cpp @@ -19,7 +19,7 @@ TEST_GROUP(TargetTestSyncGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ldd"); TEST(TargetTestSyncGroup, CopyByConstRef) { diff --git a/buildcc/lib/target/test/target/test_target_user_deps.cpp b/buildcc/lib/target/test/target/test_target_user_deps.cpp index 237da156..8a4bb451 100644 --- a/buildcc/lib/target/test/target/test_target_user_deps.cpp +++ b/buildcc/lib/target/test/target/test_target_user_deps.cpp @@ -27,7 +27,7 @@ TEST_GROUP(TargetTestUserDepsGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); static const fs::path target_source_intermediate_path = diff --git a/buildcc/lib/toolchain/include/toolchain/common/function_lock.h b/buildcc/lib/toolchain/include/toolchain/common/function_lock.h index 246b8ee7..bef3ee34 100644 --- a/buildcc/lib/toolchain/include/toolchain/common/function_lock.h +++ b/buildcc/lib/toolchain/include/toolchain/common/function_lock.h @@ -34,15 +34,13 @@ class FunctionLock { void Unlock() { SetLock(false); } bool IsLocked() const { return lock_; } - // TODO, Make this better - void ExpectsUnlock(std::string_view tag) const { + + void ExpectsUnlock(std::string_view message) const { env::assert_fatal(!lock_, - fmt::format("Cannot use {} when lock == true", tag)); + fmt::format("Expects lock == false. {}", message)); } - // TODO, Make this better - void ExpectsLock(std::string_view tag) const { - env::assert_fatal(lock_, - fmt::format("Cannot use {} when lock == false", tag)); + void ExpectsLock(std::string_view message) const { + env::assert_fatal(lock_, fmt::format("Expects lock == true. {}", message)); } private: diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index b58bf968..f46cc2ad 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -29,44 +29,66 @@ namespace buildcc { +enum class ToolchainId { + Gcc = 0, ///< GCC Toolchain + Msvc, ///< MSVC Toolchain + Clang, ///< Clang Toolchain + MinGW, ///< MinGW Toolchain (Similar to GCC, but for Windows) + Custom, ///< Custom Toolchain not defined in this list + Undefined, ///< Default value when unknown +}; + +struct ToolchainBinaries { + explicit ToolchainBinaries() = default; + explicit ToolchainBinaries(std::string_view as, std::string_view c, + std::string_view cpp, std::string_view ar, + std::string_view link) + : assembler(as), c_compiler(c), cpp_compiler(cpp), archiver(ar), + linker(link) {} + std::string assembler; + std::string c_compiler; + std::string cpp_compiler; + std::string archiver; + std::string linker; +}; + // Base toolchain class class Toolchain : public internal::FlagApi, public ToolchainVerify { public: - enum class Id { - Gcc = 0, ///< GCC Toolchain - Msvc, ///< MSVC Toolchain - Clang, ///< Clang Toolchain - MinGW, ///< MinGW Toolchain (Similar to GCC, but for Windows) - Custom, ///< Custom Toolchain not defined in this list - Undefined, ///< Default value when unknown - }; - public: - explicit Toolchain(Id id, std::string_view name, - std::string_view asm_compiler, std::string_view c_compiler, - std::string_view cpp_compiler, std::string_view archiver, - std::string_view linker, bool lock = true, - const ToolchainConfig &config = ToolchainConfig()) - : id_(id), name_(name), asm_compiler_(asm_compiler), - c_compiler_(c_compiler), cpp_compiler_(cpp_compiler), - archiver_(archiver), linker_(linker), config_(config), lock_(lock) { + Toolchain(ToolchainId id, std::string_view name, + const ToolchainBinaries &binaries, bool lock = true, + const ToolchainConfig &config = ToolchainConfig()) + : id_(id), name_(name), binaries_(binaries), lock_(lock), + config_(config) { Initialize(); } - - Toolchain(Toolchain &&toolchain) = default; - Toolchain(const Toolchain &toolchain) = delete; + Toolchain(ToolchainId id, std::string_view name, std::string_view assembler, + std::string_view c_compiler, std::string_view cpp_compiler, + std::string_view archiver, std::string_view linker, + bool lock = true, const ToolchainConfig &config = ToolchainConfig()) + : Toolchain(id, name, + ToolchainBinaries(assembler, c_compiler, cpp_compiler, + archiver, linker), + lock, config) {} + + Toolchain(Toolchain &&) = default; + Toolchain &operator=(Toolchain &&) = default; + Toolchain(const Toolchain &) = delete; + Toolchain &operator=(const Toolchain &) = delete; void Lock(); // Getters - Id GetId() const { return id_; } + ToolchainId GetId() const { return id_; } const std::string &GetName() const { return name_; } - const std::string &GetAsmCompiler() const { return asm_compiler_; } - const std::string &GetCCompiler() const { return c_compiler_; } - const std::string &GetCppCompiler() const { return cpp_compiler_; } - const std::string &GetArchiver() const { return archiver_; } - const std::string &GetLinker() const { return linker_; } + const std::string &GetAssembler() const { return binaries_.assembler; } + const std::string &GetCCompiler() const { return binaries_.c_compiler; } + const std::string &GetCppCompiler() const { return binaries_.cpp_compiler; } + const std::string &GetArchiver() const { return binaries_.archiver; } + const std::string &GetLinker() const { return binaries_.linker; } + const ToolchainBinaries &GetToolchainBinaries() const { return binaries_; } const FunctionLock &GetLockInfo() const { return lock_; } const ToolchainConfig &GetConfig() const { return config_; } @@ -89,28 +111,19 @@ class Toolchain : public internal::FlagApi, private: friend class internal::FlagApi; - - // TODO, Remove this and have a virtual `Verify` function instead - // Anti-pattern: ToolchainVerify contains GCC and MSVC specific - // implementations in a "Base" toolchain class friend class ToolchainVerify; private: - Id id_; + ToolchainId id_; std::string name_; - std::string asm_compiler_; - std::string c_compiler_; - std::string cpp_compiler_; - std::string archiver_; - std::string linker_; - ToolchainConfig config_; + ToolchainBinaries binaries_; FunctionLock lock_; + ToolchainConfig config_; // UserSchema user_; }; -typedef Toolchain::Id ToolchainId; typedef Toolchain BaseToolchain; } // namespace buildcc diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 44ce6021..157a7c1e 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -78,12 +78,12 @@ GetCompilerVersion(const fs::path &absolute_path, std::optional compiler_version; switch (toolchain.GetId()) { - case buildcc::Toolchain::Id::Gcc: - case buildcc::Toolchain::Id::MinGW: - case buildcc::Toolchain::Id::Clang: + case buildcc::ToolchainId::Gcc: + case buildcc::ToolchainId::MinGW: + case buildcc::ToolchainId::Clang: compiler_version = GetGccCompilerVersion(command); break; - case buildcc::Toolchain::Id::Msvc: + case buildcc::ToolchainId::Msvc: compiler_version = GetMsvcCompilerVersion(); break; default: @@ -127,12 +127,12 @@ GetCompilerArchitecture(const fs::path &absolute_path, (absolute_path / toolchain.GetCppCompiler()).make_preferred().string()); std::optional target_arch; switch (toolchain.GetId()) { - case buildcc::Toolchain::Id::Gcc: - case buildcc::Toolchain::Id::MinGW: - case buildcc::Toolchain::Id::Clang: + case buildcc::ToolchainId::Gcc: + case buildcc::ToolchainId::MinGW: + case buildcc::ToolchainId::Clang: target_arch = GetGccTargetArchitecture(command); break; - case buildcc::Toolchain::Id::Msvc: + case buildcc::ToolchainId::Msvc: target_arch = GetMsvcTargetArchitecture(); break; default: @@ -157,7 +157,7 @@ class ToolchainMatcher { matcher_.clear(); matcher_.insert( - fmt::format("{}{}", toolchain_.GetAsmCompiler(), os_executable_ext)); + fmt::format("{}{}", toolchain_.GetAssembler(), os_executable_ext)); matcher_.insert( fmt::format("{}{}", toolchain_.GetCCompiler(), os_executable_ext)); matcher_.insert( @@ -258,26 +258,31 @@ ToolchainVerify::Verify(const VerifyToolchainConfig &config) { "OS not supported"); verified_toolchain_ = verified_toolchains[0]; - t.asm_compiler_ = (verified_toolchain_.path / - fmt::format("{}{}", t.asm_compiler_, os_executable_ext)) - .make_preferred() - .string(); - t.c_compiler_ = (verified_toolchain_.path / - fmt::format("{}{}", t.c_compiler_, os_executable_ext)) - .make_preferred() - .string(); - t.cpp_compiler_ = (verified_toolchain_.path / - fmt::format("{}{}", t.cpp_compiler_, os_executable_ext)) - .make_preferred() - .string(); - t.archiver_ = (verified_toolchain_.path / - fmt::format("{}{}", t.archiver_, os_executable_ext)) - .make_preferred() - .string(); - t.linker_ = (verified_toolchain_.path / - fmt::format("{}{}", t.linker_, os_executable_ext)) - .make_preferred() - .string(); + t.binaries_.assembler = + (verified_toolchain_.path / + fmt::format("{}{}", t.binaries_.assembler, os_executable_ext)) + .make_preferred() + .string(); + t.binaries_.c_compiler = + (verified_toolchain_.path / + fmt::format("{}{}", t.binaries_.c_compiler, os_executable_ext)) + .make_preferred() + .string(); + t.binaries_.cpp_compiler = + (verified_toolchain_.path / + fmt::format("{}{}", t.binaries_.cpp_compiler, os_executable_ext)) + .make_preferred() + .string(); + t.binaries_.archiver = + (verified_toolchain_.path / + fmt::format("{}{}", t.binaries_.archiver, os_executable_ext)) + .make_preferred() + .string(); + t.binaries_.linker = + (verified_toolchain_.path / + fmt::format("{}{}", t.binaries_.linker, os_executable_ext)) + .make_preferred() + .string(); } return verified_toolchains; diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 9e12df5e..0fce266c 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -27,7 +27,7 @@ TEST_GROUP(ToolchainTestGroup) // NOTE, We are mocking the environment instead of actually querying it TEST(ToolchainTestGroup, VerifyToolchain_Gcc) { - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); std::vector version_stdout_data{"version"}; @@ -56,7 +56,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_Gcc) { } TEST(ToolchainTestGroup, VerifyToolchain_Clang) { - buildcc::Toolchain clang(buildcc::Toolchain::Id::Clang, "clang", "llvm-as", + buildcc::Toolchain clang(buildcc::ToolchainId::Clang, "clang", "llvm-as", "clang", "clang++", "llvm-ar", "lld"); std::vector version_stdout_data{"version"}; @@ -85,8 +85,8 @@ TEST(ToolchainTestGroup, VerifyToolchain_Clang) { } TEST(ToolchainTestGroup, VerifyToolchain_Msvc) { - buildcc::Toolchain msvc(buildcc::Toolchain::Id::Msvc, "msvc", "cl", "cl", - "cl", "lib", "link"); + buildcc::Toolchain msvc(buildcc::ToolchainId::Msvc, "msvc", "cl", "cl", "cl", + "lib", "link"); // Setup ENV // VSCMD_VER std::string vscmd_ver = std::string("VSCMD_VER=version"); @@ -122,8 +122,8 @@ TEST(ToolchainTestGroup, VerifyToolchain_Msvc) { } TEST(ToolchainTestGroup, VerifyToolchain_BadCompilerId) { - buildcc::Toolchain gcc((buildcc::Toolchain::Id)65535, "gcc", "as", "gcc", - "g++", "ar", "ld"); + buildcc::Toolchain gcc((buildcc::ToolchainId)65535, "gcc", "as", "gcc", "g++", + "ar", "ld"); std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path().string()); @@ -146,7 +146,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_BadCompilerId) { } TEST(ToolchainTestGroup, VerifyToolchain_BadAbsolutePath) { - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); buildcc::VerifyToolchainConfig config; @@ -161,7 +161,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_BadAbsolutePath) { } TEST(ToolchainTestGroup, VerifyToolchain_PathContainsDir) { - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); buildcc::VerifyToolchainConfig config; @@ -176,7 +176,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_PathContainsDir) { } TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_CompilerVersion) { - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); buildcc::VerifyToolchainConfig config; @@ -198,7 +198,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_CompilerVersion) { TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_CompilerVersionFailure) { - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); buildcc::VerifyToolchainConfig config; @@ -219,7 +219,7 @@ TEST(ToolchainTestGroup, } TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArch) { - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); buildcc::VerifyToolchainConfig config; @@ -240,7 +240,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArch) { } TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArchFailure) { - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); buildcc::VerifyToolchainConfig config; @@ -261,7 +261,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArchFailure) { } TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_BothFailure) { - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); buildcc::VerifyToolchainConfig config; @@ -283,7 +283,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_BothFailure) { } TEST(ToolchainTestGroup, VerifyToolchain_UpdateFalse) { - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); buildcc::VerifyToolchainConfig config; @@ -315,7 +315,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_LockedFolder) { FAIL_TEST("Could not set file permissions"); } - buildcc::Toolchain gcc(buildcc::Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); buildcc::VerifyToolchainConfig config; diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index ebf4be40..9e54351f 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -40,7 +40,7 @@ constexpr const char *const kGccPrefixLibDir = "-L"; class Toolchain_gcc : public Toolchain { public: Toolchain_gcc() - : Toolchain(Toolchain::Id::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld") {} + : Toolchain(ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld") {} Toolchain_gcc(const Toolchain_gcc &gcc) = delete; private: diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index 6a5a8ceb..db40a8d6 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -41,8 +41,7 @@ constexpr const char *const kMsvcPrefixLibDir = "/LIBPATH:"; class Toolchain_msvc : public Toolchain { public: Toolchain_msvc() - : Toolchain(Toolchain::Id::Msvc, "msvc", "cl", "cl", "cl", "lib", - "link") {} + : Toolchain(ToolchainId::Msvc, "msvc", "cl", "cl", "cl", "lib", "link") {} Toolchain_msvc(const Toolchain_msvc &gcc) = delete; private: diff --git a/docs/source/user_api/toolchain.rst b/docs/source/user_api/toolchain.rst index a3710106..4fd1b5ae 100644 --- a/docs/source/user_api/toolchain.rst +++ b/docs/source/user_api/toolchain.rst @@ -6,8 +6,6 @@ toolchain.h .. doxygenclass:: buildcc::Toolchain -.. doxygentypedef:: ToolchainId - .. doxygentypedef:: BaseToolchain toolchain_verify.h diff --git a/docs/source/user_api/toolchain_utils.rst b/docs/source/user_api/toolchain_utils.rst index 8c2dfcd7..3a2976ae 100644 --- a/docs/source/user_api/toolchain_utils.rst +++ b/docs/source/user_api/toolchain_utils.rst @@ -17,3 +17,10 @@ toolchain_config.h -------------------- .. doxygenstruct:: buildcc::ToolchainConfig + +toolchain.h +-------------- + +.. doxygenenum:: buildcc::ToolchainId + +.. doxygenstruct:: buildcc::ToolchainBinaries From a3d2c7fe006f55068e6fbdd81cf8f20ade5c9f0c Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Mar 2022 06:36:14 -0700 Subject: [PATCH 08/35] Toolchain find and verify (#199) - Reworked Toolchain::Find and Toolchain::Verify APIs - Added support for Custom Toolchain verification --- buildcc/lib/args/include/args/args.h | 14 +- buildcc/lib/args/src/args.cpp | 20 +- buildcc/lib/args/test/test_args.cpp | 60 +-- .../test/target/test_toolchain_flag_api.cpp | 1 + buildcc/lib/toolchain/CMakeLists.txt | 34 +- .../include/toolchain/api/toolchain_find.h | 62 +++ .../include/toolchain/api/toolchain_verify.h | 87 ++-- .../toolchain/common/toolchain_executables.h | 41 ++ .../include/toolchain/common/toolchain_id.h | 65 +++ .../toolchain/include/toolchain/toolchain.h | 56 +-- .../lib/toolchain/src/api/toolchain_find.cpp | 107 +++++ .../toolchain/src/api/toolchain_verify.cpp | 401 ++++++++-------- .../lib/toolchain/src/toolchain/toolchain.cpp | 3 + .../toolchain/test/test_toolchain_find.cpp | 102 ++++ .../lib/toolchain/test/test_toolchain_id.cpp | 50 ++ .../toolchain/test/test_toolchain_verify.cpp | 445 ++++++++++-------- .../toolchain/test/toolchains/custom/archiver | 0 .../test/toolchains/custom/archiver.exe | 0 .../test/toolchains/custom/assembler | 0 .../test/toolchains/custom/assembler.exe | 0 .../test/toolchains/custom/c_compiler | 0 .../test/toolchains/custom/c_compiler.exe | 0 .../test/toolchains/custom/cpp_compiler | 0 .../test/toolchains/custom/cpp_compiler.exe | 0 .../toolchain/test/toolchains/custom/linker | 0 .../test/toolchains/custom/linker.exe | 0 .../include/toolchains/toolchain_mingw.h | 2 + buildexe/buildexe.cpp | 3 +- buildexe/include/buildexe/toolchain_setup.h | 1 - buildexe/src/toolchain_setup.cpp | 25 - example/hybrid/single/build.cpp | 3 +- 31 files changed, 1008 insertions(+), 574 deletions(-) create mode 100644 buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h create mode 100644 buildcc/lib/toolchain/include/toolchain/common/toolchain_executables.h create mode 100644 buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h create mode 100644 buildcc/lib/toolchain/src/api/toolchain_find.cpp create mode 100644 buildcc/lib/toolchain/test/test_toolchain_find.cpp create mode 100644 buildcc/lib/toolchain/test/test_toolchain_id.cpp create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/archiver create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/archiver.exe create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/assembler create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/assembler.exe create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/c_compiler create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/c_compiler.exe create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler.exe create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/linker create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/linker.exe diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index 05311272..c687df92 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -48,8 +48,8 @@ struct ArgToolchainState { struct ArgToolchain { ArgToolchain(){}; ArgToolchain(ToolchainId initial_id, const std::string &initial_name, - const ToolchainBinaries &initial_binaries) - : id(initial_id), name(initial_name), binaries(initial_binaries) {} + const ToolchainExecutables &initial_executables) + : id(initial_id), name(initial_name), executables(initial_executables) {} ArgToolchain(ToolchainId initial_id, const std::string &initial_name, const std::string &initial_assembler, const std::string &initial_c_compiler, @@ -57,9 +57,9 @@ struct ArgToolchain { const std::string &initial_archiver, const std::string &initial_linker) : ArgToolchain(initial_id, initial_name, - ToolchainBinaries(initial_assembler, initial_c_compiler, - initial_cpp_compiler, initial_archiver, - initial_linker)) {} + ToolchainExecutables(initial_assembler, initial_c_compiler, + initial_cpp_compiler, + initial_archiver, initial_linker)) {} /** * @brief Construct a BaseToolchain from the arguments supplied through the @@ -67,13 +67,13 @@ struct ArgToolchain { */ // TODO, Update this for lock and ToolchainConfig BaseToolchain ConstructToolchain() const { - return BaseToolchain(id, name, binaries); + return BaseToolchain(id, name, executables); } ArgToolchainState state; ToolchainId id{ToolchainId::Undefined}; std::string name{""}; - ToolchainBinaries binaries; + ToolchainExecutables executables; }; // NOTE, Incomplete without pch_compile_command diff --git a/buildcc/lib/args/src/args.cpp b/buildcc/lib/args/src/args.cpp index 9c95eb5c..e6cd76a1 100644 --- a/buildcc/lib/args/src/args.cpp +++ b/buildcc/lib/args/src/args.cpp @@ -99,16 +99,16 @@ void Args::AddToolchain(const std::string &name, const std::string &description, ->transform(CLI::CheckedTransformer(kToolchainIdMap, CLI::ignore_case)) ->default_val(initial.id); t_user->add_option(kToolchainNameParam, out.name)->default_val(initial.name); - t_user->add_option(kToolchainAsmCompilerParam, out.binaries.assembler) - ->default_val(initial.binaries.assembler); - t_user->add_option(kToolchainCCompilerParam, out.binaries.c_compiler) - ->default_val(initial.binaries.c_compiler); - t_user->add_option(kToolchainCppCompilerParam, out.binaries.cpp_compiler) - ->default_val(initial.binaries.cpp_compiler); - t_user->add_option(kToolchainArchiverParam, out.binaries.archiver) - ->default_val(initial.binaries.archiver); - t_user->add_option(kToolchainLinkerParam, out.binaries.linker) - ->default_val(initial.binaries.linker); + t_user->add_option(kToolchainAsmCompilerParam, out.executables.assembler) + ->default_val(initial.executables.assembler); + t_user->add_option(kToolchainCCompilerParam, out.executables.c_compiler) + ->default_val(initial.executables.c_compiler); + t_user->add_option(kToolchainCppCompilerParam, out.executables.cpp_compiler) + ->default_val(initial.executables.cpp_compiler); + t_user->add_option(kToolchainArchiverParam, out.executables.archiver) + ->default_val(initial.executables.archiver); + t_user->add_option(kToolchainLinkerParam, out.executables.linker) + ->default_val(initial.executables.linker); } void Args::AddTarget(const std::string &name, const std::string &description, diff --git a/buildcc/lib/args/test/test_args.cpp b/buildcc/lib/args/test/test_args.cpp index b52179cf..acaa82b7 100644 --- a/buildcc/lib/args/test/test_args.cpp +++ b/buildcc/lib/args/test/test_args.cpp @@ -68,11 +68,11 @@ TEST(ArgsTestGroup, Args_CustomToolchain) { CHECK_FALSE(gcc_toolchain.state.test); CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.executables.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.executables.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.executables.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.executables.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.executables.linker.c_str(), "ld"); } TEST(ArgsTestGroup, Args_MultipleCustomToolchain) { @@ -106,22 +106,22 @@ TEST(ArgsTestGroup, Args_MultipleCustomToolchain) { CHECK_FALSE(gcc_toolchain.state.test); CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.executables.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.executables.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.executables.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.executables.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.executables.linker.c_str(), "ld"); // MSVC CHECK_TRUE(msvc_toolchain.state.build); CHECK_TRUE(msvc_toolchain.state.test); CHECK(msvc_toolchain.id == buildcc::ToolchainId::Msvc); STRCMP_EQUAL(msvc_toolchain.name.c_str(), "msvc"); - STRCMP_EQUAL(msvc_toolchain.binaries.assembler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.c_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.cpp_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.archiver.c_str(), "lib"); - STRCMP_EQUAL(msvc_toolchain.binaries.linker.c_str(), "link"); + STRCMP_EQUAL(msvc_toolchain.executables.assembler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.c_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.cpp_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.archiver.c_str(), "lib"); + STRCMP_EQUAL(msvc_toolchain.executables.linker.c_str(), "link"); } TEST(ArgsTestGroup, Args_DuplicateCustomToolchain) { @@ -167,11 +167,11 @@ TEST(ArgsTestGroup, Args_CustomTarget) { CHECK_FALSE(gcc_toolchain.state.test); CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.executables.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.executables.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.executables.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.executables.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.executables.linker.c_str(), "ld"); // Target STRCMP_EQUAL(gcc_target.compile_command.c_str(), @@ -221,11 +221,11 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { CHECK_FALSE(gcc_toolchain.state.test); CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.executables.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.executables.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.executables.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.executables.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.executables.linker.c_str(), "ld"); // Target STRCMP_EQUAL(gcc_target.compile_command.c_str(), @@ -242,11 +242,11 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { CHECK_TRUE(msvc_toolchain.state.test); CHECK(msvc_toolchain.id == buildcc::ToolchainId::Msvc); STRCMP_EQUAL(msvc_toolchain.name.c_str(), "msvc"); - STRCMP_EQUAL(msvc_toolchain.binaries.assembler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.c_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.cpp_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.archiver.c_str(), "lib"); - STRCMP_EQUAL(msvc_toolchain.binaries.linker.c_str(), "link"); + STRCMP_EQUAL(msvc_toolchain.executables.assembler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.c_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.cpp_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.archiver.c_str(), "lib"); + STRCMP_EQUAL(msvc_toolchain.executables.linker.c_str(), "link"); // Target STRCMP_EQUAL(msvc_target.compile_command.c_str(), diff --git a/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp index 3d698891..dc5aa0f7 100644 --- a/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp +++ b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp @@ -85,5 +85,6 @@ TEST(ToolchainFlagApiTestGroup, BasicTargetTest) { } int main(int ac, char **av) { + MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/toolchain/CMakeLists.txt b/buildcc/lib/toolchain/CMakeLists.txt index 91570b7d..ce4f6ac0 100644 --- a/buildcc/lib/toolchain/CMakeLists.txt +++ b/buildcc/lib/toolchain/CMakeLists.txt @@ -6,14 +6,14 @@ set(TOOLCHAIN_SRCS include/toolchain/common/function_lock.h # API + src/api/toolchain_find.cpp + src/api/toolchain_verify.cpp + include/toolchain/api/toolchain_find.h + include/toolchain/api/toolchain_verify.h include/toolchain/api/flag_api.h src/toolchain/toolchain.cpp include/toolchain/toolchain.h - - # Features - src/api/toolchain_verify.cpp - include/toolchain/api/toolchain_verify.h ) if (${TESTING}) add_library(mock_toolchain @@ -32,10 +32,10 @@ if (${TESTING}) ${TEST_LINK_LIBS} ) - add_executable(test_toolchain_verify - test/test_toolchain_verify.cpp + add_executable(test_toolchain_id + test/test_toolchain_id.cpp ) - target_link_libraries(test_toolchain_verify PRIVATE + target_link_libraries(test_toolchain_id PRIVATE mock_toolchain ) @@ -46,10 +46,28 @@ if (${TESTING}) mock_toolchain ) + add_executable(test_toolchain_find + test/test_toolchain_find.cpp + ) + target_link_libraries(test_toolchain_find PRIVATE + mock_toolchain + ) + + add_executable(test_toolchain_verify + test/test_toolchain_verify.cpp + ) + target_link_libraries(test_toolchain_verify PRIVATE + mock_toolchain + ) + + add_test(NAME test_toolchain_id COMMAND test_toolchain_id) + add_test(NAME test_toolchain_config COMMAND test_toolchain_config) + add_test(NAME test_toolchain_find COMMAND test_toolchain_find + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test + ) add_test(NAME test_toolchain_verify COMMAND test_toolchain_verify WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test ) - add_test(NAME test_toolchain_config COMMAND test_toolchain_config) endif() if(${BUILDCC_BUILD_AS_SINGLE_LIB}) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h new file mode 100644 index 00000000..4929bc5e --- /dev/null +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h @@ -0,0 +1,62 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAIN_TOOLCHAIN_FIND_H_ +#define TOOLCHAIN_TOOLCHAIN_FIND_H_ + +#include +#include +#include +#include + +#include "schema/path.h" + +namespace fs = std::filesystem; + +namespace buildcc { + +/** + * @brief Configure the behaviour of Toolchain::Find API. By default searches + * the directories mentioned in the ENV{PATH} variable to find the toolchain. + * @param absolute_search_paths absolute_search_paths expect directories that + * are iterated for exact toolchain matches + * @param env_vars env_vars contain paths that are seperated by OS delimiter. + * These are converted to paths and searched similarly to absolute_search_paths + *
+ * NOTE: env_vars must contain single absolute paths or multiple absolute + * paths seperated by OS delimiter
+ * Example: [Windows] "absolute_path_1;absolute_path_2;..."
+ * Example: [Linux] "absolute_path_1:absolute_path_2:..."
+ */ +struct ToolchainFindConfig { + ToolchainFindConfig( + const std::unordered_set &env_vars = {"PATH"}, + const fs_unordered_set &absolute_search_paths = {}) + : env_vars(env_vars), absolute_search_paths(absolute_search_paths) {} + + std::unordered_set env_vars; + fs_unordered_set absolute_search_paths; +}; + +template class ToolchainFind { +public: + std::vector + Find(const ToolchainFindConfig &config = ToolchainFindConfig()) const; +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index a22277da..1318aefd 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -21,51 +21,21 @@ #include #include +#include "fmt/format.h" + #include "env/logging.h" -#include "fmt/format.h" +#include "toolchain/common/toolchain_executables.h" +#include "toolchain/common/toolchain_id.h" + +#include "toolchain/api/toolchain_find.h" namespace fs = std::filesystem; namespace buildcc { -/** - * @brief Configure the behaviour of Toolchain::Verify API. By default searches - * the directories mentioned in the ENV{PATH} variable to find the toolchain. - * @param absolute_search_paths absolute_search_paths expect directories that - * are iterated for exact toolchain matches - * @param env_vars env_vars contain paths that are seperated by OS delimiter. - * These are converted to paths and searched similarly to absolute_search_paths - *
- * NOTE: env_vars must contain single absolute paths or multiple absolute - * paths seperated by OS delimiter
- * Example: [Windows] "absolute_path_1;absolute_path_2;..."
- * Example: [Linux] "absolute_path_1:absolute_path_2:..."
- * @param compiler_version Optionally supply a compiler version if multiple - * toolchains of the same family/id are installed
- * Example: [GCC/MinGW/Clang] {compiler} -dumpversion
- * Example: [MSVC] getenv(VSCMD_VER)
- * For [MSVC] make sure to use `vcvarsall.bat {flavour}` to activate your - * toolchain - * @param target_arch Optionally supply a target architecture if multiple - * toolchains of the same family/id are installed but target different platforms - *
- * Example: [GCC/MinGW/Clang] {compiler} -dumpmachine
- * Example: [MSVC] getenv(VSCMD_ARG_HOST_ARCH) + - * getenv(VSCMD_ARG_TGT_ARCH)
- * For [MSVC] make sure to use `vcvarsall.bat {flavour}` to activate your - * toolchain - * @param update Updates the toolchain with absolute paths once verified
- * If multiple toolchains are found, uses the first in the list - */ -struct VerifyToolchainConfig { - std::vector absolute_search_paths; - std::vector env_vars{"PATH"}; - - std::optional compiler_version; - std::optional target_arch; - - bool update{true}; +struct ToolchainVerifyConfig : public ToolchainFindConfig { + std::optional verification_identifier; }; /** @@ -76,16 +46,34 @@ struct VerifyToolchainConfig { * @param compiler_version Compiler version of the verified toolchain * @param target_arch Target architecture of the verified toolchain */ -struct VerifiedToolchain { +struct ToolchainCompilerInfo { + std::string ToString() const { return fmt::format("{}", *this); } + fs::path path; std::string compiler_version; std::string target_arch; - - std::string ToString() const { return fmt::format("{}", *this); } }; +typedef std::function( + const ToolchainExecutables &)> + ToolchainVerificationFunc; + template class ToolchainVerify { public: + ToolchainVerify() { Initialize(); } + + /** + * @brief + * + * @param id + * @param verification_func + * @param identifier Only read when ToolchainId::Custom is passed in + */ + static void + AddVerificationFunc(ToolchainId id, + const ToolchainVerificationFunc &verification_func, + const std::optional &op_identifier = {}); + /** * @brief Verify your toolchain executables by searching your operating system * paths @@ -96,11 +84,18 @@ template class ToolchainVerify { * multiple toolchains of similar names with different versions. Collect all * of them */ - std::vector - Verify(const VerifyToolchainConfig &config = VerifyToolchainConfig()); + ToolchainCompilerInfo + Verify(const ToolchainVerifyConfig &config = ToolchainVerifyConfig()); protected: - VerifiedToolchain verified_toolchain_; + ToolchainCompilerInfo verified_toolchain_; + +private: + void Initialize(); + static const ToolchainVerificationFunc & + GetVerificationFunc(const std::string &identifier); + static std::unordered_map & + GetStatic(); }; } // namespace buildcc @@ -112,9 +107,9 @@ constexpr const char *const kVerifiedToolchainFormat = R"({{ }})"; template <> -struct fmt::formatter : formatter { +struct fmt::formatter : formatter { template - auto format(const buildcc::VerifiedToolchain &vt, FormatContext &ctx) { + auto format(const buildcc::ToolchainCompilerInfo &vt, FormatContext &ctx) { std::string verified_toolchain_info = fmt::format(kVerifiedToolchainFormat, vt.path.string(), vt.compiler_version, vt.target_arch); diff --git a/buildcc/lib/toolchain/include/toolchain/common/toolchain_executables.h b/buildcc/lib/toolchain/include/toolchain/common/toolchain_executables.h new file mode 100644 index 00000000..b8862200 --- /dev/null +++ b/buildcc/lib/toolchain/include/toolchain/common/toolchain_executables.h @@ -0,0 +1,41 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAIN_COMMON_TOOLCHAIN_EXECUTABLES_H_ +#define TOOLCHAIN_COMMON_TOOLCHAIN_EXECUTABLES_H_ + +#include +#include + +namespace buildcc { + +struct ToolchainExecutables { + explicit ToolchainExecutables() = default; + explicit ToolchainExecutables(std::string_view as, std::string_view c, + std::string_view cpp, std::string_view ar, + std::string_view link) + : assembler(as), c_compiler(c), cpp_compiler(cpp), archiver(ar), + linker(link) {} + std::string assembler; + std::string c_compiler; + std::string cpp_compiler; + std::string archiver; + std::string linker; +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h b/buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h new file mode 100644 index 00000000..d19ea6d6 --- /dev/null +++ b/buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h @@ -0,0 +1,65 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAIN_COMMON_TOOLCHAIN_ID_H_ +#define TOOLCHAIN_COMMON_TOOLCHAIN_ID_H_ + +#include "fmt/format.h" + +namespace buildcc { + +enum class ToolchainId { + Gcc = 0, ///< GCC Toolchain + Msvc, ///< MSVC Toolchain + Clang, ///< Clang Toolchain + MinGW, ///< MinGW Toolchain (Similar to GCC, but for Windows) + Custom, ///< Custom Toolchain not defined in this list + Undefined, ///< Default value when unknown +}; + +} // namespace buildcc + +template <> +struct fmt::formatter : formatter { + template + auto format(buildcc::ToolchainId id, FormatContext &ctx) { + std::string id_name; + switch (id) { + case buildcc::ToolchainId::Gcc: + id_name = "Gcc"; + break; + case buildcc::ToolchainId::Msvc: + id_name = "Msvc"; + break; + case buildcc::ToolchainId::Clang: + id_name = "Clang"; + break; + case buildcc::ToolchainId::MinGW: + id_name = "MinGW"; + break; + case buildcc::ToolchainId::Custom: + id_name = "Custom"; + break; + case buildcc::ToolchainId::Undefined: + default: + id_name = "Undefined"; + break; + } + return formatter::format(id_name, ctx); + } +}; + +#endif diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index f46cc2ad..7ae3e959 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -23,44 +23,25 @@ #include "toolchain/common/function_lock.h" #include "toolchain/common/toolchain_config.h" +#include "toolchain/common/toolchain_executables.h" +#include "toolchain/common/toolchain_id.h" #include "toolchain/api/flag_api.h" +#include "toolchain/api/toolchain_find.h" #include "toolchain/api/toolchain_verify.h" namespace buildcc { -enum class ToolchainId { - Gcc = 0, ///< GCC Toolchain - Msvc, ///< MSVC Toolchain - Clang, ///< Clang Toolchain - MinGW, ///< MinGW Toolchain (Similar to GCC, but for Windows) - Custom, ///< Custom Toolchain not defined in this list - Undefined, ///< Default value when unknown -}; - -struct ToolchainBinaries { - explicit ToolchainBinaries() = default; - explicit ToolchainBinaries(std::string_view as, std::string_view c, - std::string_view cpp, std::string_view ar, - std::string_view link) - : assembler(as), c_compiler(c), cpp_compiler(cpp), archiver(ar), - linker(link) {} - std::string assembler; - std::string c_compiler; - std::string cpp_compiler; - std::string archiver; - std::string linker; -}; - // Base toolchain class class Toolchain : public internal::FlagApi, + public ToolchainFind, public ToolchainVerify { public: public: Toolchain(ToolchainId id, std::string_view name, - const ToolchainBinaries &binaries, bool lock = true, + const ToolchainExecutables &executables, bool lock = true, const ToolchainConfig &config = ToolchainConfig()) - : id_(id), name_(name), binaries_(binaries), lock_(lock), + : id_(id), name_(name), executables_(executables), lock_(lock), config_(config) { Initialize(); } @@ -69,8 +50,8 @@ class Toolchain : public internal::FlagApi, std::string_view archiver, std::string_view linker, bool lock = true, const ToolchainConfig &config = ToolchainConfig()) : Toolchain(id, name, - ToolchainBinaries(assembler, c_compiler, cpp_compiler, - archiver, linker), + ToolchainExecutables(assembler, c_compiler, cpp_compiler, + archiver, linker), lock, config) {} Toolchain(Toolchain &&) = default; @@ -83,12 +64,16 @@ class Toolchain : public internal::FlagApi, // Getters ToolchainId GetId() const { return id_; } const std::string &GetName() const { return name_; } - const std::string &GetAssembler() const { return binaries_.assembler; } - const std::string &GetCCompiler() const { return binaries_.c_compiler; } - const std::string &GetCppCompiler() const { return binaries_.cpp_compiler; } - const std::string &GetArchiver() const { return binaries_.archiver; } - const std::string &GetLinker() const { return binaries_.linker; } - const ToolchainBinaries &GetToolchainBinaries() const { return binaries_; } + const std::string &GetAssembler() const { return executables_.assembler; } + const std::string &GetCCompiler() const { return executables_.c_compiler; } + const std::string &GetCppCompiler() const { + return executables_.cpp_compiler; + } + const std::string &GetArchiver() const { return executables_.archiver; } + const std::string &GetLinker() const { return executables_.linker; } + const ToolchainExecutables &GetToolchainExecutables() const { + return executables_; + } const FunctionLock &GetLockInfo() const { return lock_; } const ToolchainConfig &GetConfig() const { return config_; } @@ -106,9 +91,10 @@ class Toolchain : public internal::FlagApi, }; private: - virtual void UpdateConfig(ToolchainConfig &config) { (void)config; } void Initialize(); + virtual void UpdateConfig(ToolchainConfig &config); + private: friend class internal::FlagApi; friend class ToolchainVerify; @@ -116,7 +102,7 @@ class Toolchain : public internal::FlagApi, private: ToolchainId id_; std::string name_; - ToolchainBinaries binaries_; + ToolchainExecutables executables_; FunctionLock lock_; ToolchainConfig config_; diff --git a/buildcc/lib/toolchain/src/api/toolchain_find.cpp b/buildcc/lib/toolchain/src/api/toolchain_find.cpp new file mode 100644 index 00000000..bdef49b3 --- /dev/null +++ b/buildcc/lib/toolchain/src/api/toolchain_find.cpp @@ -0,0 +1,107 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "toolchain/api/toolchain_find.h" + +#include "env/assert_fatal.h" +#include "env/host_os.h" +#include "env/host_os_util.h" +#include "env/util.h" + +#include "toolchain/toolchain.h" + +namespace { + +std::vector ParseEnvVarToPaths(const std::string &env_var) { + const char *path_env = getenv(env_var.c_str()); + buildcc::env::assert_fatal( + path_env != nullptr, + fmt::format("Environment variable '{}' not present", env_var)); + + constexpr const char *os_env_delim = buildcc::env::get_os_envvar_delim(); + buildcc::env::assert_fatal("OS not supported"); + std::vector paths = + buildcc::env::split(path_env, os_env_delim[0]); + + return paths; +} + +bool ContainsToolchainExecutables( + const fs::directory_iterator &directory_iterator, + const buildcc::ToolchainExecutables &executables) { + std::unordered_set exes( + {executables.assembler, executables.c_compiler, executables.cpp_compiler, + executables.archiver, executables.linker}); + std::error_code ec; + for (const auto &dir_iter : directory_iterator) { + bool is_regular_file = dir_iter.is_regular_file(ec); + if (!is_regular_file || ec) { + continue; + } + const auto &filename_without_ext = dir_iter.path().stem().string(); + // NOTE, Must match the entire filename + exes.erase(filename_without_ext); + } + return exes.empty(); +} + +} // namespace + +namespace buildcc { + +template +std::vector +ToolchainFind::Find(const ToolchainFindConfig &config) const { + // Initialization + const T &t = static_cast(*this); + std::vector found_toolchains; + fs_unordered_set absolute_search_paths(config.absolute_search_paths); + + // Parse config envs and add it to absolute search paths + for (const std::string &env_var : config.env_vars) { + std::vector paths = ParseEnvVarToPaths(env_var); + absolute_search_paths.insert(paths.begin(), paths.end()); + } + + // Over the absolute search paths + // - Check if directory exists + // - Iterate over directory + // - Find ALL Toolchain binaries in ONE directory + // - If matched, store that path + for (const auto &search_path : absolute_search_paths) { + if (!fs::exists(search_path)) { + continue; + } + + std::error_code ec; + auto directory_iterator = fs::directory_iterator(search_path, ec); + if (ec) { + continue; + } + + bool toolchains_matched = ContainsToolchainExecutables( + directory_iterator, t.GetToolchainExecutables()); + if (toolchains_matched) { + found_toolchains.push_back(search_path); + } + } + + return found_toolchains; +} + +template class ToolchainFind; + +} // namespace buildcc diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 157a7c1e..1d60b80f 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -22,7 +22,7 @@ #include -#include "toolchain/toolchain.h" +#include "schema/path.h" #include "env/assert_fatal.h" #include "env/host_os.h" @@ -31,261 +31,238 @@ #include "env/command.h" -namespace { -// Constants - -// Functions -std::vector ParseEnvVarToPaths(const std::string &env_var) { - const char *path_env = getenv(env_var.c_str()); - buildcc::env::assert_fatal( - path_env != nullptr, - fmt::format("Environment variable '{}' not present", env_var)); - - constexpr const char *os_env_delim = buildcc::env::get_os_envvar_delim(); - buildcc::env::assert_fatal("OS not supported"); - std::vector paths = - buildcc::env::split(path_env, os_env_delim[0]); +#include "toolchain/toolchain.h" - return paths; -} +namespace { -std::string GetGccCompilerVersion(const buildcc::env::Command &command) { +std::optional +GetGccCompilerVersion(const buildcc::env::Command &command) { std::vector stdout_data; bool executed = buildcc::env::Command::Execute( command.Construct("{compiler} -dumpversion"), {}, &stdout_data); - buildcc::env::assert_fatal( - executed, "GetCompilerVersion command not executed successfully"); - return stdout_data.at(0); + if (!executed || stdout_data.empty()) { + return {}; + } + return stdout_data[0]; } -std::string GetMsvcCompilerVersion() { - // Done VSCMD_VER - const char *vscmd_version = getenv("VSCMD_VER"); - buildcc::env::assert_fatal( - vscmd_version != nullptr, - "Setup Visual Studio build tools. Call `vcvarsall.bat {platform}` to " - "setup your target and host"); - return vscmd_version; +std::optional +GetGccTargetArchitecture(const buildcc::env::Command &command) { + std::vector stdout_data; + bool executed = buildcc::env::Command::Execute( + command.Construct("{compiler} -dumpmachine"), {}, &stdout_data); + if (!executed || stdout_data.empty()) { + return {}; + } + return stdout_data[0]; } -std::optional -GetCompilerVersion(const fs::path &absolute_path, - const buildcc::Toolchain &toolchain) { +std::optional +GccVerificationFunc(const buildcc::ToolchainExecutables &executables) { buildcc::env::Command command; - command.AddDefaultArgument( - "compiler", - (absolute_path / toolchain.GetCppCompiler()).make_preferred().string()); + command.AddDefaultArgument("compiler", executables.cpp_compiler); - std::optional compiler_version; - switch (toolchain.GetId()) { - case buildcc::ToolchainId::Gcc: - case buildcc::ToolchainId::MinGW: - case buildcc::ToolchainId::Clang: - compiler_version = GetGccCompilerVersion(command); - break; - case buildcc::ToolchainId::Msvc: - compiler_version = GetMsvcCompilerVersion(); - break; - default: - buildcc::env::log_warning(__FUNCTION__, - "Operation not supported on this compiler"); - compiler_version = {}; - break; + auto op_compiler_version = GetGccCompilerVersion(command); + auto op_target_arch = GetGccTargetArchitecture(command); + if (!op_compiler_version.has_value() || !op_target_arch.has_value()) { + return {}; } - return compiler_version; + + buildcc::ToolchainCompilerInfo compiler_info; + compiler_info.compiler_version = op_compiler_version.value(); + compiler_info.target_arch = op_target_arch.value(); + return compiler_info; } -std::string GetGccTargetArchitecture(const buildcc::env::Command &command) { - std::vector stdout_data; - bool executed = buildcc::env::Command::Execute( - command.Construct("{compiler} -dumpmachine"), {}, &stdout_data); - buildcc::env::assert_fatal( - executed, "GetCompilerArchitecture command not executed successfully"); - return stdout_data.at(0); +std::optional GetMsvcCompilerVersion() { + const char *vscmd_version = getenv("VSCMD_VER"); + if (vscmd_version == nullptr) { + return {}; + } + return vscmd_version; } -std::string GetMsvcTargetArchitecture() { +std::optional GetMsvcTargetArchitecture() { // DONE, Read `VSCMD_ARG_HOST_ARCH` from env path // DONE, Read `VSCMD_ARG_TGT_ARCH` from env path const char *vs_host_arch = getenv("VSCMD_ARG_HOST_ARCH"); const char *vs_target_arch = getenv("VSCMD_ARG_TGT_ARCH"); - buildcc::env::assert_fatal( - (vs_host_arch != nullptr) && (vs_target_arch != nullptr), - "Setup Visual Studio build tools. Call `vcvarsall.bat {platform}` to " - "setup your target and host"); + if (vs_host_arch == nullptr || vs_target_arch == nullptr) { + return {}; + } - // DONE, Concat them! + // DONE, Concat them return fmt::format("{}_{}", vs_host_arch, vs_target_arch); } -std::optional -GetCompilerArchitecture(const fs::path &absolute_path, - const buildcc::Toolchain &toolchain) { - buildcc::env::Command command; - command.AddDefaultArgument( - "compiler", - (absolute_path / toolchain.GetCppCompiler()).make_preferred().string()); - std::optional target_arch; - switch (toolchain.GetId()) { - case buildcc::ToolchainId::Gcc: - case buildcc::ToolchainId::MinGW: - case buildcc::ToolchainId::Clang: - target_arch = GetGccTargetArchitecture(command); +std::optional +MsvcVerificationFunc(const buildcc::ToolchainExecutables &executables) { + (void)executables; + auto op_compiler_version = GetMsvcCompilerVersion(); + auto op_target_arch = GetMsvcTargetArchitecture(); + if (!op_compiler_version.has_value() || !op_target_arch.has_value()) { + return {}; + } + + buildcc::ToolchainCompilerInfo compiler_info; + compiler_info.compiler_version = op_compiler_version.value(); + compiler_info.target_arch = op_target_arch.value(); + return compiler_info; +} + +// + +buildcc::ToolchainExecutables CreateToolchainExecutables( + const fs::path &absolute_path, + const buildcc::ToolchainExecutables ¤t_executables) { + constexpr const char *const executable_ext = + buildcc::env::get_os_executable_extension(); + buildcc::env::assert_fatal( + "Host executable extension not supported"); + + std::string assembler_path = + (absolute_path / + fmt::format("{}{}", current_executables.assembler, executable_ext)) + .string(); + std::string c_compiler_path = + (absolute_path / + fmt::format("{}{}", current_executables.c_compiler, executable_ext)) + .string(); + std::string cpp_compiler_path = + (absolute_path / + fmt::format("{}{}", current_executables.cpp_compiler, executable_ext)) + .string(); + std::string archiver_path = + (absolute_path / + fmt::format("{}{}", current_executables.archiver, executable_ext)) + .string(); + std::string linker_path = + (absolute_path / + fmt::format("{}{}", current_executables.linker, executable_ext)) + .string(); + + return buildcc::ToolchainExecutables(assembler_path, c_compiler_path, + cpp_compiler_path, archiver_path, + linker_path); +} + +std::string +GetToolchainVerifyIdentifier(buildcc::ToolchainId id, + const std::optional &op_identifier) { + std::string identifier; + switch (id) { + case buildcc::ToolchainId::Custom: + buildcc::env::assert_fatal( + op_identifier.has_value(), + "Requires verification_identifier value in ToolchainVerifyConfig"); + identifier = op_identifier.value(); break; + case buildcc::ToolchainId::Gcc: case buildcc::ToolchainId::Msvc: - target_arch = GetMsvcTargetArchitecture(); + case buildcc::ToolchainId::Clang: + case buildcc::ToolchainId::MinGW: + identifier = fmt::format("{}", id); break; + case buildcc::ToolchainId::Undefined: default: - buildcc::env::log_warning(__FUNCTION__, - "Operation not supported on this compiler"); - target_arch = {}; + buildcc::env::assert_fatal( + "Undefined toolchain. Use valid ToolchainId"); break; } - return target_arch; + return identifier; } -class ToolchainMatcher { -public: - explicit ToolchainMatcher(const buildcc::Toolchain &toolchain) - : toolchain_(toolchain) {} - - void FillWithToolchainFilenames() { - constexpr const char *os_executable_ext = - buildcc::env::get_os_executable_extension(); - buildcc::env::assert_fatal( - "OS not supported"); - - matcher_.clear(); - matcher_.insert( - fmt::format("{}{}", toolchain_.GetAssembler(), os_executable_ext)); - matcher_.insert( - fmt::format("{}{}", toolchain_.GetCCompiler(), os_executable_ext)); - matcher_.insert( - fmt::format("{}{}", toolchain_.GetCppCompiler(), os_executable_ext)); - matcher_.insert( - fmt::format("{}{}", toolchain_.GetArchiver(), os_executable_ext)); - matcher_.insert( - fmt::format("{}{}", toolchain_.GetLinker(), os_executable_ext)); - } - - void Check(const std::string &filename) { matcher_.erase(filename); } - bool Found() { return matcher_.empty(); } - -private: - const buildcc::Toolchain &toolchain_; - - std::unordered_set matcher_; -}; - } // namespace namespace buildcc { template -std::vector -ToolchainVerify::Verify(const VerifyToolchainConfig &config) { - // TODO, Convert this to fs::path eventually - std::unordered_set absolute_search_paths{ - config.absolute_search_paths.begin(), config.absolute_search_paths.end()}; - - // Parse config envs - for (const std::string &env_var : config.env_vars) { - std::vector paths = ParseEnvVarToPaths(env_var); - for (const auto &p : paths) { - absolute_search_paths.insert(p); - } +void ToolchainVerify::AddVerificationFunc( + ToolchainId id, const ToolchainVerificationFunc &verification_func, + const std::optional &op_identifier) { + std::string identifier; + switch (id) { + case ToolchainId::Gcc: + case ToolchainId::Msvc: + case ToolchainId::MinGW: + case ToolchainId::Clang: + identifier = fmt::format("{}", id); + break; + case ToolchainId::Custom: + env::assert_fatal(op_identifier.has_value(), + "Requires optional identifier parameter when " + "ToolchainId::Custom is defined"); + identifier = op_identifier.value(); + break; + default: + env::assert_fatal("Invalid ToolchainId parameter"); + break; } - std::vector verified_toolchains; + env::assert_fatal( + ToolchainVerify::GetStatic().count(identifier) == 0, + fmt::format("Already registered VerificationFunction for identifier '{}'", + identifier)); + ToolchainVerify::GetStatic()[identifier] = verification_func; +} + +template +ToolchainCompilerInfo +ToolchainVerify::Verify(const ToolchainVerifyConfig &config) { T &t = static_cast(*this); + std::vector toolchain_paths = t.Find(config); + env::assert_fatal(!toolchain_paths.empty(), "No toolchains found"); - ToolchainMatcher matcher(t); - matcher.FillWithToolchainFilenames(); - // Iterate over absolute search paths - // [Verification] Match ALL toolchains PER directory - for (const std::string &pstr : absolute_search_paths) { - fs::path p{pstr}; - if (!fs::exists(p)) { - continue; - } - - std::error_code ec; - auto directory_iterator = fs::directory_iterator(p, ec); - if (ec) { - continue; - } - - // For each directory, Check if ALL toolchain filenames are found - for (const auto &dir_iter : directory_iterator) { - bool is_regular_file = dir_iter.is_regular_file(ec); - if (!is_regular_file || ec) { - continue; - } - const auto &filename = dir_iter.path().filename().string(); - matcher.Check(filename); - } - - // Store verified toolchain path if found - if (matcher.Found()) { - env::log_info(__FUNCTION__, fmt::format("Found: {}", p.string())); - - VerifiedToolchain vt; - vt.path = p; - vt.compiler_version = env::trim(GetCompilerVersion(p, t).value_or("")); - vt.target_arch = env::trim(GetCompilerArchitecture(p, t).value_or("")); - - // Check add - bool add{true}; - if (config.compiler_version.has_value()) { - add = add && (config.compiler_version.value() == vt.compiler_version); - } - if (config.target_arch.has_value()) { - add = add && (config.target_arch.value() == vt.target_arch); - } - if (add) { - verified_toolchains.push_back(vt); - } - } - - // Reset - matcher.FillWithToolchainFilenames(); - } + ToolchainExecutables exes = + CreateToolchainExecutables(toolchain_paths[0], t.executables_); + + std::string toolchain_id_identifier = + GetToolchainVerifyIdentifier(t.GetId(), config.verification_identifier); + + const auto &verification_func = + T::GetVerificationFunc(toolchain_id_identifier); + auto op_toolchain_compiler_info = verification_func(exes); + env::assert_fatal(op_toolchain_compiler_info.has_value(), + "Could not verify toolchain"); + + ToolchainCompilerInfo toolchain_compiler_info = + op_toolchain_compiler_info.value(); + toolchain_compiler_info.path = toolchain_paths[0]; - if (config.update && !verified_toolchains.empty()) { - constexpr const char *os_executable_ext = - buildcc::env::get_os_executable_extension(); - buildcc::env::assert_fatal( - "OS not supported"); - - verified_toolchain_ = verified_toolchains[0]; - t.binaries_.assembler = - (verified_toolchain_.path / - fmt::format("{}{}", t.binaries_.assembler, os_executable_ext)) - .make_preferred() - .string(); - t.binaries_.c_compiler = - (verified_toolchain_.path / - fmt::format("{}{}", t.binaries_.c_compiler, os_executable_ext)) - .make_preferred() - .string(); - t.binaries_.cpp_compiler = - (verified_toolchain_.path / - fmt::format("{}{}", t.binaries_.cpp_compiler, os_executable_ext)) - .make_preferred() - .string(); - t.binaries_.archiver = - (verified_toolchain_.path / - fmt::format("{}{}", t.binaries_.archiver, os_executable_ext)) - .make_preferred() - .string(); - t.binaries_.linker = - (verified_toolchain_.path / - fmt::format("{}{}", t.binaries_.linker, os_executable_ext)) - .make_preferred() - .string(); + // Update the compilers + t.executables_ = exes; + return toolchain_compiler_info; +} + +// PRIVATE +template void ToolchainVerify::Initialize() { + static bool do_once = true; + + if (do_once) { + do_once = false; + AddVerificationFunc(ToolchainId::Gcc, GccVerificationFunc); + AddVerificationFunc(ToolchainId::Msvc, MsvcVerificationFunc); + AddVerificationFunc(ToolchainId::Clang, GccVerificationFunc); + AddVerificationFunc(ToolchainId::MinGW, GccVerificationFunc); } +} - return verified_toolchains; +template +const ToolchainVerificationFunc & +ToolchainVerify::GetVerificationFunc(const std::string &identifier) { + const auto &verification_map = T::GetStatic(); + env::assert_fatal(verification_map.count(identifier) == 1, + "Add verification for custom toolchain through " + "Toolchain::AddVerificationFunc API"); + return verification_map.at(identifier); +} + +template +std::unordered_map & +ToolchainVerify::GetStatic() { + static std::unordered_map + verification_func_map; + return verification_func_map; } template class ToolchainVerify; diff --git a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp index 3a3ae354..53bee71c 100644 --- a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp +++ b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp @@ -22,4 +22,7 @@ void Toolchain::Initialize() { UpdateConfig(config_); } void Toolchain::Lock() { lock_.Lock(); } +// PRIVATE +void Toolchain::UpdateConfig(ToolchainConfig &config) { (void)config; } + } // namespace buildcc diff --git a/buildcc/lib/toolchain/test/test_toolchain_find.cpp b/buildcc/lib/toolchain/test/test_toolchain_find.cpp new file mode 100644 index 00000000..3867b8ac --- /dev/null +++ b/buildcc/lib/toolchain/test/test_toolchain_find.cpp @@ -0,0 +1,102 @@ +#include + +#include "toolchain/toolchain.h" + +#include "env/host_os.h" + +#include "expect_command.h" + +#include "mock_command_copier.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(ToolchainFindTestGroup) +{ + void teardown() { + mock().checkExpectations(); + mock().clear(); + } +}; +// clang-format on + +TEST(ToolchainFindTestGroup, FindToolchain_ThroughEnvVar) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", + fs::current_path().string()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainFindConfig config; + config.env_vars.clear(); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + std::vector found_toolchains = gcc.Find(config); + CHECK_TRUE(!found_toolchains.empty()); +} + +TEST(ToolchainFindTestGroup, FindToolchain_ThroughAbsolutePath) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + buildcc::ToolchainFindConfig config; + config.absolute_search_paths.insert(fs::current_path() / "toolchains" / + "gcc"); + config.env_vars.clear(); + + std::vector found_toolchains = gcc.Find(config); + CHECK_TRUE(!found_toolchains.empty()); +} + +TEST(ToolchainFindTestGroup, FindToolchain_DirectoryDoesntExist) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + buildcc::ToolchainFindConfig config; + config.absolute_search_paths.insert(fs::current_path() / "toolchains" / + "directory_doesnt_exist"); + config.env_vars.clear(); + + std::vector found_toolchains = gcc.Find(config); + CHECK_TRUE(found_toolchains.empty()); +} + +TEST(ToolchainFindTestGroup, FindToolchain_NoDirectoryFound) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + buildcc::ToolchainFindConfig config; + config.absolute_search_paths.insert(fs::current_path() / "toolchains" / + "gcc" / "ar"); + config.env_vars.clear(); + + std::vector found_toolchains = gcc.Find(config); + CHECK_TRUE(found_toolchains.empty()); +} + +TEST(ToolchainFindTestGroup, FindToolchain_NoToolchainFound) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + buildcc::ToolchainFindConfig config; + config.absolute_search_paths.insert(fs::current_path() / "toolchains"); + config.env_vars.clear(); + + std::vector found_toolchains = gcc.Find(config); + CHECK_TRUE(found_toolchains.empty()); +} + +int main(int ac, char **av) { + MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/lib/toolchain/test/test_toolchain_id.cpp b/buildcc/lib/toolchain/test/test_toolchain_id.cpp new file mode 100644 index 00000000..6cb77e6b --- /dev/null +++ b/buildcc/lib/toolchain/test/test_toolchain_id.cpp @@ -0,0 +1,50 @@ +#include + +#include "toolchain/common/toolchain_id.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(ToolchainIdTestGroup) +{ + void teardown() { + mock().checkExpectations(); + mock().clear(); + } +}; +// clang-format on + +TEST(ToolchainIdTestGroup, ToolchainIdAsString) { + std::string compiler; + + compiler = fmt::format("{}", buildcc::ToolchainId::Gcc); + STRCMP_EQUAL(compiler.c_str(), "Gcc"); + + compiler = fmt::format("{}", buildcc::ToolchainId::Msvc); + STRCMP_EQUAL(compiler.c_str(), "Msvc"); + + compiler = fmt::format("{}", buildcc::ToolchainId::Clang); + STRCMP_EQUAL(compiler.c_str(), "Clang"); + + compiler = fmt::format("{}", buildcc::ToolchainId::MinGW); + STRCMP_EQUAL(compiler.c_str(), "MinGW"); + + compiler = fmt::format("{}", buildcc::ToolchainId::Custom); + STRCMP_EQUAL(compiler.c_str(), "Custom"); + + compiler = fmt::format("{}", buildcc::ToolchainId::Undefined); + STRCMP_EQUAL(compiler.c_str(), "Undefined"); + + compiler = fmt::format("{}", (buildcc::ToolchainId)65535); + STRCMP_EQUAL(compiler.c_str(), "Undefined"); +} + +int main(int ac, char **av) { + MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 0fce266c..5854191d 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -16,7 +16,7 @@ #include "CppUTestExt/MockSupport.h" // clang-format off -TEST_GROUP(ToolchainTestGroup) +TEST_GROUP(ToolchainVerifyTestGroup) { void teardown() { mock().checkExpectations(); @@ -26,7 +26,7 @@ TEST_GROUP(ToolchainTestGroup) // clang-format on // NOTE, We are mocking the environment instead of actually querying it -TEST(ToolchainTestGroup, VerifyToolchain_Gcc) { +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); @@ -35,279 +35,333 @@ TEST(ToolchainTestGroup, VerifyToolchain_Gcc) { buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); - std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", - fs::current_path().string()); + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); int put = putenv(putenv_str.data()); CHECK_TRUE(put == 0); const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(!verified_toolchains.empty()); - STRCMP_EQUAL(verified_toolchains[0].compiler_version.c_str(), "version"); - STRCMP_EQUAL(verified_toolchains[0].target_arch.c_str(), "arch"); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + buildcc::ToolchainCompilerInfo compiler_info = gcc.Verify(config); + + STRCMP_EQUAL(compiler_info.compiler_version.c_str(), "version"); + STRCMP_EQUAL(compiler_info.target_arch.c_str(), "arch"); } -TEST(ToolchainTestGroup, VerifyToolchain_Clang) { - buildcc::Toolchain clang(buildcc::ToolchainId::Clang, "clang", "llvm-as", - "clang", "clang++", "llvm-ar", "lld"); +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionFailure) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); std::vector version_stdout_data{"version"}; std::vector arch_stdout_data{"arch"}; - buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, false, &version_stdout_data); buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); - std::string putenv_str = fmt::format( - "CUSTOM_BUILDCC_PATH={}/toolchains/clang", fs::current_path().string()); + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); int put = putenv(putenv_str.data()); CHECK_TRUE(put == 0); const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); - - std::vector verified_toolchains = - clang.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(!verified_toolchains.empty()); - STRCMP_EQUAL(verified_toolchains[0].compiler_version.c_str(), "version"); - STRCMP_EQUAL(verified_toolchains[0].target_arch.c_str(), "arch"); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + CHECK_THROWS(std::exception, gcc.Verify(config)); } -TEST(ToolchainTestGroup, VerifyToolchain_Msvc) { - buildcc::Toolchain msvc(buildcc::ToolchainId::Msvc, "msvc", "cl", "cl", "cl", - "lib", "link"); - // Setup ENV - // VSCMD_VER - std::string vscmd_ver = std::string("VSCMD_VER=version"); - // VSCMD_ARG_HOST_ARCH - std::string host_arch = std::string("VSCMD_ARG_HOST_ARCH=host_arch"); - // VSCMD_ARG_TGT_ARCH - std::string tgt_arch = std::string("VSCMD_ARG_TGT_ARCH=tgt_arch"); +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionEmpty) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); - CHECK_TRUE(putenv(vscmd_ver.data()) == 0); - CHECK_TRUE(putenv(host_arch.data()) == 0); - CHECK_TRUE(putenv(tgt_arch.data()) == 0); + std::vector version_stdout_data; + std::vector arch_stdout_data{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); - // MSVC Compiler - std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/msvc", - fs::current_path().string()); + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); int put = putenv(putenv_str.data()); CHECK_TRUE(put == 0); const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); - - std::vector verified_toolchains = - msvc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(!verified_toolchains.empty()); - STRCMP_EQUAL(verified_toolchains[0].compiler_version.c_str(), "version"); - STRCMP_EQUAL(verified_toolchains[0].target_arch.c_str(), - "host_arch_tgt_arch"); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + CHECK_THROWS(std::exception, gcc.Verify(config)); } -TEST(ToolchainTestGroup, VerifyToolchain_BadCompilerId) { - buildcc::Toolchain gcc((buildcc::ToolchainId)65535, "gcc", "as", "gcc", "g++", +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchFailure) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", - fs::current_path().string()); + std::vector version_stdout_data{"version"}; + std::vector arch_stdout_data{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, false, &arch_stdout_data); + + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); int put = putenv(putenv_str.data()); CHECK_TRUE(put == 0); const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(!verified_toolchains.empty()); - STRCMP_EQUAL(verified_toolchains[0].compiler_version.c_str(), ""); - STRCMP_EQUAL(verified_toolchains[0].target_arch.c_str(), ""); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + CHECK_THROWS(std::exception, gcc.Verify(config)); } -TEST(ToolchainTestGroup, VerifyToolchain_BadAbsolutePath) { +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchEmpty) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + std::vector version_stdout_data{"version"}; + std::vector arch_stdout_data; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); + + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( - (fs::current_path() / "does_not_exist").string()); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(verified_toolchains.empty()); + CHECK_THROWS(std::exception, gcc.Verify(config)); } -TEST(ToolchainTestGroup, VerifyToolchain_PathContainsDir) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Clang) { + buildcc::Toolchain clang(buildcc::ToolchainId::Clang, "clang", "llvm-as", + "clang", "clang++", "llvm-ar", "lld"); + + std::vector version_stdout_data{"version"}; + std::vector arch_stdout_data{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); - buildcc::VerifyToolchainConfig config; + std::string putenv_str = fmt::format( + "CUSTOM_BUILDCC_PATH={}/toolchains/clang", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( - (fs::current_path() / "toolchains").string()); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + buildcc::ToolchainCompilerInfo compiler_info = clang.Verify(config); - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(verified_toolchains.empty()); + STRCMP_EQUAL(compiler_info.compiler_version.c_str(), "version"); + STRCMP_EQUAL(compiler_info.target_arch.c_str(), "arch"); } -TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_CompilerVersion) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Msvc) { + buildcc::Toolchain msvc(buildcc::ToolchainId::Msvc, "msvc", "cl", "cl", "cl", + "lib", "link"); + // Setup ENV + // VSCMD_VER + std::string vscmd_ver = std::string("VSCMD_VER=version"); + // VSCMD_ARG_HOST_ARCH + std::string host_arch = std::string("VSCMD_ARG_HOST_ARCH=host_arch"); + // VSCMD_ARG_TGT_ARCH + std::string tgt_arch = std::string("VSCMD_ARG_TGT_ARCH=tgt_arch"); - buildcc::VerifyToolchainConfig config; - config.env_vars.clear(); - config.absolute_search_paths.push_back( - (fs::current_path() / "toolchains" / "gcc").string()); - config.compiler_version = "10.2.1"; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"none"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 1); -} + CHECK_TRUE(putenv(vscmd_ver.data()) == 0); + CHECK_TRUE(putenv(host_arch.data()) == 0); + CHECK_TRUE(putenv(tgt_arch.data()) == 0); -TEST(ToolchainTestGroup, - VerifyToolchain_ConditionalAdd_CompilerVersionFailure) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + // MSVC Compiler + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/msvc", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( - (fs::current_path() / "toolchains" / "gcc").string()); - config.compiler_version = "11.0.0"; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"none"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 0); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + buildcc::ToolchainCompilerInfo compiler_info = msvc.Verify(config); + + STRCMP_EQUAL(compiler_info.compiler_version.c_str(), "version"); + STRCMP_EQUAL(compiler_info.target_arch.c_str(), "host_arch_tgt_arch"); } -TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArch) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Custom_VerificationSuccess) { + buildcc::Toolchain::AddVerificationFunc( + buildcc::ToolchainId::Custom, + [](const buildcc::ToolchainExecutables &executables) + -> std::optional { + (void)executables; + buildcc::ToolchainCompilerInfo compiler_info; + compiler_info.compiler_version = "custom_compiler_version"; + compiler_info.target_arch = "custom_target_arch"; + return compiler_info; + }, + "success_verification_func"); + buildcc::Toolchain custom(buildcc::ToolchainId::Custom, "custom", "assembler", + "c_compiler", "cpp_compiler", "archiver", "linker"); + buildcc::ToolchainVerifyConfig config; + config.env_vars.clear(); + config.absolute_search_paths.insert( + (fs::current_path() / "toolchains" / "custom")); + config.verification_identifier = "success_verification_func"; + auto compiler_info = custom.Verify(config); + STRCMP_EQUAL(compiler_info.compiler_version.c_str(), + "custom_compiler_version"); + STRCMP_EQUAL(compiler_info.target_arch.c_str(), "custom_target_arch"); +} - buildcc::VerifyToolchainConfig config; +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Custom_VerificationFailure) { + buildcc::Toolchain::AddVerificationFunc( + buildcc::ToolchainId::Custom, + [](const buildcc::ToolchainExecutables &executables) + -> std::optional { + (void)executables; + return {}; + }, + "failure_verification_func"); + + // Adding verification function with the same identifier throws an exception + CHECK_THROWS(std::exception, + (buildcc::Toolchain::AddVerificationFunc( + buildcc::ToolchainId::Custom, + [](const buildcc::ToolchainExecutables &executables) + -> std::optional { + (void)executables; + return {}; + }, + "failure_verification_func"))); + buildcc::Toolchain custom(buildcc::ToolchainId::Custom, "custom", "assembler", + "c_compiler", "cpp_compiler", "archiver", "linker"); + + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( - (fs::current_path() / "toolchains" / "gcc").string()); - config.target_arch = "arm-none-eabi"; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"arm-none-eabi"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 1); + config.absolute_search_paths.insert( + (fs::current_path() / "toolchains" / "custom")); + // Fails since ToolchainId::Custom expects a verification_identifier + CHECK_THROWS(std::exception, custom.Verify(config)); + + // Fails since we do not get valid ToolchainCompilerInfo + config.verification_identifier = "failure_verification_func"; + CHECK_THROWS(std::exception, custom.Verify(config)); + + // Fails since we have not registered a verification function with this id + config.verification_identifier = "unregistered_verification_func"; + CHECK_THROWS(std::exception, custom.Verify(config)); } -TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArchFailure) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Undefined_AddVerificationFunc) { + CHECK_THROWS(std::exception, + (buildcc::Toolchain::AddVerificationFunc( + buildcc::ToolchainId::Undefined, + [](const buildcc::ToolchainExecutables &executables) + -> std::optional { + (void)executables; + return {}; + }, + "undefined_verification_func"))); +} + +TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadCompilerId) { + buildcc::Toolchain gcc((buildcc::ToolchainId)65535, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( - (fs::current_path() / "toolchains" / "gcc").string()); - config.target_arch = "none"; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"arm-none-eabi"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 0); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + CHECK_THROWS(std::exception, gcc.Verify(config)); } -TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_BothFailure) { +TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadAbsolutePath) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( - (fs::current_path() / "toolchains" / "gcc").string()); - config.compiler_version = "none"; - config.target_arch = "none"; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"arm-none-eabi"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 0); + config.absolute_search_paths.insert((fs::current_path() / "does_not_exist")); + + CHECK_THROWS(std::exception, gcc.Verify(config)); } -TEST(ToolchainTestGroup, VerifyToolchain_UpdateFalse) { +TEST(ToolchainVerifyTestGroup, VerifyToolchain_PathContainsDir) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( - (fs::current_path() / "toolchains" / "gcc").string()); - // config.compiler_version = "none"; - // config.target_arch = "none"; - config.update = false; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"arm-none-eabi"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 1); + config.absolute_search_paths.insert((fs::current_path() / "toolchains")); + + CHECK_THROWS(std::exception, gcc.Verify(config)); } #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__MINGW64__) -TEST(ToolchainTestGroup, VerifyToolchain_LockedFolder) { +TEST(ToolchainVerifyTestGroup, + VerifyToolchain_Msvc_CompilerVersionAndTargetArchFailure) { + buildcc::Toolchain msvc(buildcc::ToolchainId::Msvc, "msvc", "cl", "cl", "cl", + "lib", "link"); + // Setup ENV + // VSCMD_VER + // std::string vscmd_ver = std::string("VSCMD_VER=version"); + // // VSCMD_ARG_HOST_ARCH + // std::string host_arch = std::string("VSCMD_ARG_HOST_ARCH=host_arch"); + // // VSCMD_ARG_TGT_ARCH + // std::string tgt_arch = std::string("VSCMD_ARG_TGT_ARCH=tgt_arch"); + + // CHECK_TRUE(putenv(vscmd_ver.data()) == 0); + // CHECK_TRUE(putenv(host_arch.data()) == 0); + // CHECK_TRUE(putenv(tgt_arch.data()) == 0); + + // MSVC Compiler + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/msvc", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; + config.env_vars.clear(); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + CHECK_THROWS(std::exception, msvc.Verify(config)); +} + +TEST(ToolchainVerifyTestGroup, VerifyToolchain_LockedFolder) { std::error_code err; fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::none, err); @@ -318,15 +372,12 @@ TEST(ToolchainTestGroup, VerifyToolchain_LockedFolder) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( - (fs::current_path() / "toolchains" / "gcc").string()); + config.absolute_search_paths.insert( + (fs::current_path() / "toolchains" / "gcc")); - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(verified_toolchains.empty()); + CHECK_THROWS(std::exception, gcc.Verify(config)); fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::all, err); @@ -351,6 +402,6 @@ int main(int ac, char **av) { // toolchains/msvc // toolchains/mingw // TODO, Check executables used in clang - + MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/toolchain/test/toolchains/custom/archiver b/buildcc/lib/toolchain/test/toolchains/custom/archiver new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/archiver.exe b/buildcc/lib/toolchain/test/toolchains/custom/archiver.exe new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/assembler b/buildcc/lib/toolchain/test/toolchains/custom/assembler new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/assembler.exe b/buildcc/lib/toolchain/test/toolchains/custom/assembler.exe new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/c_compiler b/buildcc/lib/toolchain/test/toolchains/custom/c_compiler new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/c_compiler.exe b/buildcc/lib/toolchain/test/toolchains/custom/c_compiler.exe new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler b/buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler.exe b/buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler.exe new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/linker b/buildcc/lib/toolchain/test/toolchains/custom/linker new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/linker.exe b/buildcc/lib/toolchain/test/toolchains/custom/linker.exe new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index 05bef7ca..d0e76824 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -19,6 +19,8 @@ #include "toolchain/toolchain.h" +#include "toolchain_gcc.h" + namespace buildcc { constexpr const char *const kMingwObjExt = ".o"; diff --git a/buildexe/buildexe.cpp b/buildexe/buildexe.cpp index faa7ede4..5b0cc000 100644 --- a/buildexe/buildexe.cpp +++ b/buildexe/buildexe.cpp @@ -60,7 +60,8 @@ int main(int argc, char **argv) { // Host Toolchain BaseToolchain toolchain = buildexe_args.GetHostToolchainArg().ConstructToolchain(); - find_toolchain_verify(toolchain); + toolchain.Verify(); + if (buildexe_args.GetBuildMode() == BuildExeMode::Script) { host_toolchain_verify(toolchain); } diff --git a/buildexe/include/buildexe/toolchain_setup.h b/buildexe/include/buildexe/toolchain_setup.h index 423bbbf4..2f87b9f3 100644 --- a/buildexe/include/buildexe/toolchain_setup.h +++ b/buildexe/include/buildexe/toolchain_setup.h @@ -21,7 +21,6 @@ namespace buildcc { -void find_toolchain_verify(BaseToolchain &toolchain); void host_toolchain_verify(const BaseToolchain &toolchain); } // namespace buildcc diff --git a/buildexe/src/toolchain_setup.cpp b/buildexe/src/toolchain_setup.cpp index 198bf40d..b007f51b 100644 --- a/buildexe/src/toolchain_setup.cpp +++ b/buildexe/src/toolchain_setup.cpp @@ -24,31 +24,6 @@ constexpr const char *const kTag = "BuildExe"; namespace buildcc { -void find_toolchain_verify(BaseToolchain &toolchain) { - auto verified_toolchains = toolchain.Verify(); - env::assert_fatal(!verified_toolchains.empty(), - "Toolchain could not be verified. Please input correct " - "Gcc, Msvc, Clang or MinGW toolchain executable names"); - if (verified_toolchains.size() > 1) { - env::log_info( - kTag, - fmt::format( - "Found {} toolchains. By default using the first added" - "toolchain. Modify your environment `PATH` information if you " - "would like compiler precedence when similar compilers are " - "detected in different folders", - verified_toolchains.size())); - } - - // Print - int counter = 1; - for (const auto &vt : verified_toolchains) { - std::string info = fmt::format("{}. : {}", counter, vt.ToString()); - env::log_info("Host Toolchain", info); - counter++; - } -} - void host_toolchain_verify(const BaseToolchain &toolchain) { env::log_info(kTag, "*** Starting Toolchain verification ***"); diff --git a/example/hybrid/single/build.cpp b/example/hybrid/single/build.cpp index 3abace55..b8b104d5 100644 --- a/example/hybrid/single/build.cpp +++ b/example/hybrid/single/build.cpp @@ -24,8 +24,7 @@ int main(int argc, char **argv) { // 4. Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; - auto verified_toolchains = gcc.Verify(); - env::assert_fatal(!verified_toolchains.empty(), "GCC Toolchain not found"); + gcc.Verify(); ExecutableTarget_gcc hello_world("hello_world", gcc, ""); From 70ca2583edec9e9a51f53f6a8b3ee3d4c9509f02 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 26 Mar 2022 23:46:35 -0700 Subject: [PATCH 09/35] Refactor `env.h` free functions to static `Project` class (#201) --- bootstrap/main.buildcc.cpp | 3 +- buildcc/lib/args/src/register.cpp | 4 +- .../lib/args/test/test_persistent_storage.cpp | 2 +- buildcc/lib/args/test/test_register.cpp | 28 ++++---- buildcc/lib/env/CMakeLists.txt | 4 ++ buildcc/lib/env/include/env/env.h | 30 ++++---- buildcc/lib/env/src/env.cpp | 59 +++++++++------- buildcc/lib/env/test/test_static_project.cpp | 28 ++++++++ .../target/include/target/common/target_env.h | 11 ++- .../lib/target/src/generator/generator.cpp | 4 +- buildcc/lib/target/src/generator/task.cpp | 4 +- .../src/target/friend/compile_object.cpp | 4 +- buildcc/lib/target/src/target/target.cpp | 6 +- buildcc/lib/target/src/target/tasks.cpp | 9 ++- .../target/test/target/test_base_target.cpp | 19 +++--- .../test/target/test_compile_object.cpp | 7 +- .../lib/target/test/target/test_generator.cpp | 10 ++- .../test/target/test_target_external_lib.cpp | 4 +- .../target/test_target_failure_states.cpp | 6 +- .../target/test/target/test_target_flags.cpp | 3 +- .../test/target/test_target_include_dir.cpp | 4 +- .../test/target/test_target_lib_dep.cpp | 4 +- .../target/test/target/test_target_lock.cpp | 3 +- .../target/test/target/test_target_pch.cpp | 3 +- .../target/test/target/test_target_source.cpp | 3 +- .../target/test_target_source_out_of_root.cpp | 4 +- .../target/test/target/test_target_sync.cpp | 5 +- .../test/target/test_target_user_deps.cpp | 8 +-- .../include/toolchain/api/toolchain_verify.h | 6 +- .../include/plugins/clang_compile_commands.h | 2 +- .../plugins/src/clang_compile_commands.cpp | 4 +- buildexe/buildexe.cpp | 4 +- buildexe/src/toolchain_setup.cpp | 2 +- docs/source/user_api/environment.rst | 6 +- docs/source/user_api/toolchain.rst | 68 +++++++++++++++++-- docs/source/user_api/toolchain_utils.rst | 9 ++- example/buildexe/libs/build.main.cpp | 6 +- example/gcc/AfterInstall/build.cpp | 2 +- example/gcc/DynamicLib/build.cpp | 2 +- example/gcc/Flags/build.cpp | 2 +- example/gcc/IncludeDir/build.cpp | 2 +- example/gcc/Plugins/build.cpp | 2 +- example/gcc/Simple/build.cpp | 2 +- example/gcc/StaticLib/build.cpp | 2 +- example/hybrid/custom_target/build.main.cpp | 4 +- example/hybrid/dep_chaining/build.cpp | 8 +-- example/hybrid/external_lib/build.main.cpp | 4 +- example/hybrid/foolib/build.main.cpp | 4 +- example/hybrid/generic/build.cpp | 6 +- example/hybrid/pch/build.cpp | 4 +- example/hybrid/simple/build.cpp | 4 +- example/hybrid/single/build.cpp | 4 +- example/hybrid/target_info/build.cpp | 4 +- example/mingw/DynamicLib/build.cpp | 2 +- example/mingw/Executable/build.cpp | 2 +- example/mingw/Pch/build.cpp | 2 +- example/mingw/StaticLib/build.cpp | 2 +- example/msvc/DynamicLib/build.cpp | 2 +- example/msvc/Executable/build.cpp | 2 +- example/msvc/StaticLib/build.cpp | 2 +- 60 files changed, 277 insertions(+), 179 deletions(-) create mode 100644 buildcc/lib/env/test/test_static_project.cpp diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index 8ec1d5a7..7f08c37b 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -44,8 +44,7 @@ int main(int argc, char **argv) { BaseToolchain toolchain = custom_toolchain_arg.ConstructToolchain(); BuildBuildCC buildcc( - reg, toolchain, - TargetEnv(env::get_project_root_dir(), env::get_project_build_dir())); + reg, toolchain, TargetEnv(Project::GetRootDir(), Project::GetBuildDir())); buildcc.Setup(custom_toolchain_arg.state); const auto &buildcc_lib = buildcc.GetBuildcc(); diff --git a/buildcc/lib/args/src/register.cpp b/buildcc/lib/args/src/register.cpp index a697fc92..680071d8 100644 --- a/buildcc/lib/args/src/register.cpp +++ b/buildcc/lib/args/src/register.cpp @@ -119,8 +119,8 @@ void Register::BuildStoreTask(const std::string &unique_id, void Register::Initialize() { Env(); } void Register::Env() { - env::init(fs::current_path() / args_.GetProjectRootDir(), - fs::current_path() / args_.GetProjectBuildDir()); + Project::Init(fs::current_path() / args_.GetProjectRootDir(), + fs::current_path() / args_.GetProjectBuildDir()); env::set_log_level(args_.GetLogLevel()); } diff --git a/buildcc/lib/args/test/test_persistent_storage.cpp b/buildcc/lib/args/test/test_persistent_storage.cpp index 97cc167a..56163d43 100644 --- a/buildcc/lib/args/test/test_persistent_storage.cpp +++ b/buildcc/lib/args/test/test_persistent_storage.cpp @@ -55,6 +55,6 @@ TEST(PersistentStorageTestGroup, NullptrDelete) { } int main(int ac, char **av) { - buildcc::env::init(fs::current_path(), fs::current_path()); + buildcc::Project::Init(fs::current_path(), fs::current_path()); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/args/test/test_register.cpp b/buildcc/lib/args/test/test_register.cpp index 0ccea4bc..948ba972 100644 --- a/buildcc/lib/args/test/test_register.cpp +++ b/buildcc/lib/args/test/test_register.cpp @@ -99,7 +99,7 @@ TEST(RegisterTestGroup, Register_Build) { CHECK_TRUE(args.Clean()); // Make dummy toolchain and target - buildcc::env::init(fs::current_path(), fs::current_path()); + buildcc::Project::Init(fs::current_path(), fs::current_path()); buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, @@ -122,7 +122,7 @@ TEST(RegisterTestGroup, Register_Build) { state, [](buildcc::BaseTarget &target) { (void)target; }, target); } - buildcc::env::deinit(); + buildcc::Project::Deinit(); mock().checkExpectations(); } @@ -147,7 +147,7 @@ TEST(RegisterTestGroup, Register_NoBuildAndDep) { CHECK_TRUE(args.Clean()); // Make dummy toolchain and target - buildcc::env::init(fs::current_path(), fs::current_path()); + buildcc::Project::Init(fs::current_path(), fs::current_path()); buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, @@ -206,7 +206,7 @@ TEST(RegisterTestGroup, Register_NoBuildAndDep) { reg.Dep(target, dependency); } - buildcc::env::deinit(); + buildcc::Project::Deinit(); mock().checkExpectations(); } @@ -231,7 +231,7 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { CHECK_TRUE(args.Clean()); // Make dummy toolchain and target - buildcc::env::init(fs::current_path(), fs::current_path()); + buildcc::Project::Init(fs::current_path(), fs::current_path()); buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, @@ -301,7 +301,7 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { reg.Dep(target, dependency); } - buildcc::env::deinit(); + buildcc::Project::Deinit(); mock().checkExpectations(); } @@ -326,7 +326,7 @@ TEST(RegisterTestGroup, Register_DepDuplicate) { CHECK_TRUE(args.Clean()); // Make dummy toolchain and target - buildcc::env::init(fs::current_path(), fs::current_path()); + buildcc::Project::Init(fs::current_path(), fs::current_path()); buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, @@ -377,7 +377,7 @@ TEST(RegisterTestGroup, Register_DepDuplicate) { CHECK_THROWS(std::exception, reg.Dep(target, dependency2)); } - buildcc::env::deinit(); + buildcc::Project::Deinit(); mock().checkExpectations(); } @@ -402,7 +402,7 @@ TEST(RegisterTestGroup, Register_DepCyclic) { CHECK_TRUE(args.Clean()); // Make dummy toolchain and target - buildcc::env::init(fs::current_path(), fs::current_path()); + buildcc::Project::Init(fs::current_path(), fs::current_path()); buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, @@ -452,7 +452,7 @@ TEST(RegisterTestGroup, Register_DepCyclic) { CHECK_THROWS(std::exception, reg.Dep(dependency2, target)); } - buildcc::env::deinit(); + buildcc::Project::Deinit(); mock().checkExpectations(); } @@ -478,7 +478,7 @@ TEST(RegisterTestGroup, Register_Test) { CHECK_TRUE(args.Clean()); // Make dummy toolchain and target - buildcc::env::init(fs::current_path(), fs::current_path()); + buildcc::Project::Init(fs::current_path(), fs::current_path()); buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, @@ -537,7 +537,7 @@ TEST(RegisterTestGroup, Register_Test) { reg.RunTest(); } - buildcc::env::deinit(); + buildcc::Project::Deinit(); mock().checkExpectations(); } @@ -563,7 +563,7 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { CHECK_TRUE(args.Clean()); // Make dummy toolchain and target - buildcc::env::init(fs::current_path(), fs::current_path()); + buildcc::Project::Init(fs::current_path(), fs::current_path()); buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", ""); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, @@ -676,7 +676,7 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { CHECK_THROWS(std::exception, reg.RunTest()); } - buildcc::env::deinit(); + buildcc::Project::Deinit(); mock().checkExpectations(); } diff --git a/buildcc/lib/env/CMakeLists.txt b/buildcc/lib/env/CMakeLists.txt index 93afa078..f76bcc34 100644 --- a/buildcc/lib/env/CMakeLists.txt +++ b/buildcc/lib/env/CMakeLists.txt @@ -26,6 +26,9 @@ if (${TESTING}) target_link_options(mock_env PUBLIC ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS}) # Tests + add_executable(test_static_project test/test_static_project.cpp) + target_link_libraries(test_static_project PRIVATE mock_env) + add_executable(test_env_util test/test_env_util.cpp) target_link_libraries(test_env_util PRIVATE mock_env) @@ -35,6 +38,7 @@ if (${TESTING}) add_executable(test_command test/test_command.cpp) target_link_libraries(test_command PRIVATE mock_env) + add_test(NAME test_static_project COMMAND test_static_project) add_test(NAME test_env_util COMMAND test_env_util) add_test(NAME test_task_state COMMAND test_task_state) add_test(NAME test_command COMMAND test_command) diff --git a/buildcc/lib/env/include/env/env.h b/buildcc/lib/env/include/env/env.h index efb6ead1..e9b9fb78 100644 --- a/buildcc/lib/env/include/env/env.h +++ b/buildcc/lib/env/include/env/env.h @@ -23,22 +23,24 @@ namespace fs = std::filesystem; -namespace buildcc::env { +namespace buildcc { -/** - * @brief Initialize project environment - * - * @param project_root_dir Root directory for source files - * @param project_build_dir Directory for intermediate build files - */ -void init(const fs::path &project_root_dir, const fs::path &project_build_dir); -void deinit(); +class Project { +public: + static void Init(const fs::path &project_root_dir, + const fs::path &project_build_dir); + static void Deinit(); + + static bool IsInit(); + static const fs::path &GetRootDir(); + static const fs::path &GetBuildDir(); -// Getters -bool is_init(); -const fs::path &get_project_root_dir(); -const fs::path &get_project_build_dir(); +private: + static bool &GetStaticInit(); + static fs::path &GetStaticRootDir(); + static fs::path &GetStaticBuildDir(); +}; -} // namespace buildcc::env +} // namespace buildcc #endif diff --git a/buildcc/lib/env/src/env.cpp b/buildcc/lib/env/src/env.cpp index ffb0f008..64ed8404 100644 --- a/buildcc/lib/env/src/env.cpp +++ b/buildcc/lib/env/src/env.cpp @@ -17,38 +17,45 @@ #include "env/env.h" #include "env/logging.h" -namespace { +namespace buildcc { -fs::path root_dir_{""}; -fs::path build_dir_{""}; -bool init_ = false; - -} // namespace - -namespace buildcc::env { - -void init(const fs::path &project_root_dir, const fs::path &project_build_dir) { +void Project::Init(const fs::path &project_root_dir, + const fs::path &project_build_dir) { // State - root_dir_ = project_root_dir; - build_dir_ = project_build_dir; - root_dir_.make_preferred(); - build_dir_.make_preferred(); + fs::path root_dir = project_root_dir; + fs::path build_dir = project_build_dir; + root_dir.make_preferred(); + build_dir.make_preferred(); - init_ = true; + GetStaticRootDir() = root_dir; + GetStaticBuildDir() = build_dir; + GetStaticInit() = true; // Logging - set_log_pattern("%^[%l]%$ %v"); - set_log_level(LogLevel::Info); + env::set_log_pattern("%^[%l]%$ %v"); + env::set_log_level(env::LogLevel::Info); } - -void deinit() { - root_dir_ = ""; - build_dir_ = ""; - init_ = false; +void Project::Deinit() { + GetStaticRootDir() = ""; + GetStaticBuildDir() = ""; + GetStaticInit() = false; } -bool is_init(void) { return init_; } -const fs::path &get_project_root_dir() { return root_dir_; } -const fs::path &get_project_build_dir() { return build_dir_; } +bool Project::IsInit() { return GetStaticInit(); } +const fs::path &Project::GetRootDir() { return GetStaticRootDir(); } +const fs::path &Project::GetBuildDir() { return GetStaticBuildDir(); } + +bool &Project::GetStaticInit() { + static bool is_init = false; + return is_init; +} +fs::path &Project::GetStaticRootDir() { + static fs::path root_dir = ""; + return root_dir; +} +fs::path &Project::GetStaticBuildDir() { + static fs::path build_dir = ""; + return build_dir; +} -} // namespace buildcc::env +} // namespace buildcc diff --git a/buildcc/lib/env/test/test_static_project.cpp b/buildcc/lib/env/test/test_static_project.cpp new file mode 100644 index 00000000..b5b4a5aa --- /dev/null +++ b/buildcc/lib/env/test/test_static_project.cpp @@ -0,0 +1,28 @@ +#include "env/env.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" + +// clang-format off +TEST_GROUP(StaticProjectTestGroup) +{ + void setup() { + } +}; +// clang-format on + +TEST(StaticProjectTestGroup, ProjectInitialized) { + CHECK_FALSE(buildcc::Project::IsInit()); + buildcc::Project::Init(fs::current_path(), fs::current_path()); + CHECK_TRUE(buildcc::Project::IsInit()); + buildcc::Project::Deinit(); + CHECK_FALSE(buildcc::Project::IsInit()); +} + +int main(int ac, char **av) { + MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/lib/target/include/target/common/target_env.h b/buildcc/lib/target/include/target/common/target_env.h index e6f129e0..322d7213 100644 --- a/buildcc/lib/target/include/target/common/target_env.h +++ b/buildcc/lib/target/include/target/common/target_env.h @@ -35,14 +35,14 @@ class TargetEnv { * @brief Change the relative root path for a particular Generator / Target * * Absolute root now changes to - * `env::get_project_root_dir() / target_relative_to_env_root` + * `Project::GetRootDir() / target_relative_to_env_root` * * Absolute build dir remains the same. * * Can be used implicitly * * @param target_relative_to_env_root Change root dir with respect to - * env::get_project_root_dir() + * Project::GetRootDir() */ TargetEnv(const char *target_relative_to_env_root) : TargetEnv(fs::path(target_relative_to_env_root)) {} @@ -53,12 +53,11 @@ class TargetEnv { * Only explicit usage allowed * * @param target_relative_to_env_root Change root dir with respect to - * env::get_project_root_dir() + * Project::GetRootDir() */ explicit TargetEnv(const fs::path &target_relative_to_env_root) - : target_root_dir_(env::get_project_root_dir() / - target_relative_to_env_root), - target_build_dir_(env::get_project_build_dir()), relative_(true) {} + : target_root_dir_(Project::GetRootDir() / target_relative_to_env_root), + target_build_dir_(Project::GetBuildDir()), relative_(true) {} /** * @brief Change the absolute root and build path for a particular Generator / diff --git a/buildcc/lib/target/src/generator/generator.cpp b/buildcc/lib/target/src/generator/generator.cpp index bd935db3..5faab606 100644 --- a/buildcc/lib/target/src/generator/generator.cpp +++ b/buildcc/lib/target/src/generator/generator.cpp @@ -79,8 +79,8 @@ Generator::GetValueByIdentifier(const std::string &file_identifier) const { void Generator::Initialize() { // Checks env::assert_fatal( - env::is_init(), - "Environment is not initialized. Use the buildcc::env::init API"); + Project::IsInit(), + "Environment is not initialized. Use the buildcc::Project::Init API"); // fs::create_directories(generator_build_dir_); diff --git a/buildcc/lib/target/src/generator/task.cpp b/buildcc/lib/target/src/generator/task.cpp index c4118114..60e396fe 100644 --- a/buildcc/lib/target/src/generator/task.cpp +++ b/buildcc/lib/target/src/generator/task.cpp @@ -79,14 +79,14 @@ void Generator::GenerateTask() { // Graph Generation for (const auto &i : user_.inputs) { std::string name = - fmt::format("{}", i.lexically_relative(env::get_project_root_dir())); + fmt::format("{}", i.lexically_relative(Project::GetRootDir())); tf::Task task = subflow.placeholder().name(name); task.precede(command_task); } for (const auto &o : user_.outputs) { std::string name = - fmt::format("{}", o.lexically_relative(env::get_project_root_dir())); + fmt::format("{}", o.lexically_relative(Project::GetRootDir())); tf::Task task = subflow.placeholder().name(name); task.succeed(command_task); } diff --git a/buildcc/lib/target/src/target/friend/compile_object.cpp b/buildcc/lib/target/src/target/friend/compile_object.cpp index c9b46bdf..5fa43bc4 100644 --- a/buildcc/lib/target/src/target/friend/compile_object.cpp +++ b/buildcc/lib/target/src/target/friend/compile_object.cpp @@ -82,9 +82,9 @@ CompileObject::GetObjectData(const fs::path &absolute_source) const { // PRIVATE // NOTE: If RELATIVE TargetEnv supplied -// {target_root_dir} => `env::get_project_root_dir()` / +// {target_root_dir} => `Project::GetRootDir()` / // `target_relative_to_root` -// {target_build_dir} => `env::get_project_build_dir()` / `toolchain.GetName()` +// {target_build_dir} => `Project::GetBuildDir()` / `toolchain.GetName()` // / `name` // Scenarios diff --git a/buildcc/lib/target/src/target/target.cpp b/buildcc/lib/target/src/target/target.cpp index ab5532bd..6a2b6a98 100644 --- a/buildcc/lib/target/src/target/target.cpp +++ b/buildcc/lib/target/src/target/target.cpp @@ -49,15 +49,15 @@ namespace buildcc { void Target::Initialize() { // Checks env::assert_fatal( - env::is_init(), - "Environment is not initialized. Use the buildcc::env::init API"); + Project::IsInit(), + "Environment is not initialized. Use the buildcc::Project::Init API"); env::assert_fatal(IsValidTargetType(type_), "Invalid Target Type"); fs::create_directories(GetTargetBuildDir()); // String updates unique_id_ = fmt::format("[{}] {}", toolchain_.GetName(), name_); std::string path = fmt::format( - "{}", GetTargetPath().lexically_relative(env::get_project_build_dir())); + "{}", GetTargetPath().lexically_relative(Project::GetBuildDir())); tf_.name(path); } diff --git a/buildcc/lib/target/src/target/tasks.cpp b/buildcc/lib/target/src/target/tasks.cpp index 0efb6e54..7b659787 100644 --- a/buildcc/lib/target/src/target/tasks.cpp +++ b/buildcc/lib/target/src/target/tasks.cpp @@ -88,7 +88,7 @@ void CompilePch::Task() { // For Graph generation for (const auto &p : target_.GetPchFiles()) { std::string name = - fmt::format("{}", p.lexically_relative(env::get_project_root_dir())); + fmt::format("{}", p.lexically_relative(Project::GetRootDir())); subflow.placeholder().name(name); } }); @@ -117,8 +117,8 @@ void CompileObject::Task() { } for (const auto &s : selected_source_files) { - std::string name = fmt::format("{}", s.GetPathname().lexically_relative( - env::get_project_root_dir())); + std::string name = fmt::format( + "{}", s.GetPathname().lexically_relative(Project::GetRootDir())); (void)subflow .emplace([this, s]() { try { @@ -136,8 +136,7 @@ void CompileObject::Task() { // For graph generation for (const auto &ds : selected_dummy_source_files) { std::string name = fmt::format( - "{}", - ds.GetPathname().lexically_relative(env::get_project_root_dir())); + "{}", ds.GetPathname().lexically_relative(Project::GetRootDir())); (void)subflow.placeholder().name(name); } } catch (...) { diff --git a/buildcc/lib/target/test/target/test_base_target.cpp b/buildcc/lib/target/test/target/test_base_target.cpp index 6f772d7d..ddc4990d 100644 --- a/buildcc/lib/target/test/target/test_base_target.cpp +++ b/buildcc/lib/target/test/target/test_base_target.cpp @@ -27,7 +27,8 @@ static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", TEST(TargetBaseTestGroup, InvalidTargetType) { constexpr const char *const INVALID_NAME = "Invalid.random"; - buildcc::env::init(BUILD_SCRIPT_SOURCE, BUILD_TARGET_BASE_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_BASE_INTERMEDIATE_DIR); auto intermediate_path = fs::path(BUILD_TARGET_BASE_INTERMEDIATE_DIR) / gcc.GetName(); @@ -37,7 +38,7 @@ TEST(TargetBaseTestGroup, InvalidTargetType) { std::exception, buildcc::BaseTarget(INVALID_NAME, (buildcc::TargetType)3, gcc, "")); - buildcc::env::deinit(); + buildcc::Project::Deinit(); } TEST(TargetBaseTestGroup, NoEnvInit) { @@ -49,9 +50,10 @@ TEST(TargetBaseTestGroup, NoEnvInit) { } TEST(TargetBaseTestGroup, TargetConfig_BadCompileCommand) { - buildcc::env::init(BUILD_SCRIPT_SOURCE, BUILD_TARGET_BASE_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_BASE_INTERMEDIATE_DIR); fs::path target_source_intermediate_path = - buildcc::env::get_project_build_dir() / gcc.GetName(); + buildcc::Project::GetBuildDir() / gcc.GetName(); constexpr const char *const NAME = "BadCompileCommand.exe"; auto intermediate_path = target_source_intermediate_path / NAME; @@ -68,13 +70,14 @@ TEST(TargetBaseTestGroup, TargetConfig_BadCompileCommand) { CHECK_THROWS(std::exception, simple.Build()); } - buildcc::env::deinit(); + buildcc::Project::Deinit(); } TEST(TargetBaseTestGroup, TargetConfig_BadLinkCommand) { - buildcc::env::init(BUILD_SCRIPT_SOURCE, BUILD_TARGET_BASE_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_BASE_INTERMEDIATE_DIR); fs::path target_source_intermediate_path = - buildcc::env::get_project_build_dir() / gcc.GetName(); + buildcc::Project::GetBuildDir() / gcc.GetName(); constexpr const char *const NAME = "BadCompileCommand.exe"; auto intermediate_path = target_source_intermediate_path / NAME; @@ -90,7 +93,7 @@ TEST(TargetBaseTestGroup, TargetConfig_BadLinkCommand) { CHECK_THROWS(std::exception, simple.Build()); } - buildcc::env::deinit(); + buildcc::Project::Deinit(); mock().checkExpectations(); } diff --git a/buildcc/lib/target/test/target/test_compile_object.cpp b/buildcc/lib/target/test/target/test_compile_object.cpp index 1819509d..8c5f1f8e 100644 --- a/buildcc/lib/target/test/target/test_compile_object.cpp +++ b/buildcc/lib/target/test/target/test_compile_object.cpp @@ -30,8 +30,9 @@ TEST(TargetCompileObjectTestGroup, CacheCompileCommand_Invalid) { } int main(int ac, char **av) { - buildcc::env::init(fs::current_path(), fs::current_path() / "intermediate" / - "target_compile_object"); - fs::remove_all(buildcc::env::get_project_build_dir()); + buildcc::Project::Init(fs::current_path(), fs::current_path() / + "intermediate" / + "target_compile_object"); + fs::remove_all(buildcc::Project::GetBuildDir()); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_generator.cpp b/buildcc/lib/target/test/target/test_generator.cpp index 169e31cf..dc7b6375 100644 --- a/buildcc/lib/target/test/target/test_generator.cpp +++ b/buildcc/lib/target/test/target/test_generator.cpp @@ -163,10 +163,8 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Inputs) { buildcc::m::blocking_sleep(1); bool saved = buildcc::env::save_file( - (buildcc::env::get_project_root_dir() / "new_source.cpp") - .string() - .c_str(), - "", false); + (buildcc::Project::GetRootDir() / "new_source.cpp").string().c_str(), "", + false); CHECK_TRUE(saved); // Updated @@ -366,7 +364,7 @@ TEST(GeneratorTestGroup, Generator_FailedGenerateCommand) { TEST(GeneratorTestGroup, Generator_FailedStore) { constexpr const char *const NAME = "FailedStore"; - const fs::path test_build_dir = buildcc::env::get_project_build_dir() / NAME; + const fs::path test_build_dir = buildcc::Project::GetBuildDir() / NAME; buildcc::Generator generator(NAME, "", false); fs::remove_all(test_build_dir); @@ -481,6 +479,6 @@ TEST(GeneratorTestGroup, FailedGenerateCommand_Rebuild) { int main(int ac, char **av) { fs::remove_all(BUILD_DIR); - buildcc::env::init(fs::current_path() / "data", BUILD_DIR); + buildcc::Project::Init(fs::current_path() / "data", BUILD_DIR); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_external_lib.cpp b/buildcc/lib/target/test/target/test_target_external_lib.cpp index 6c04a79c..4a979b6d 100644 --- a/buildcc/lib/target/test/target/test_target_external_lib.cpp +++ b/buildcc/lib/target/test/target/test_target_external_lib.cpp @@ -141,7 +141,7 @@ TEST(TargetTestExternalLib, TestAddExternalLibDep_RebuildChanged) { } int main(int ac, char **av) { - buildcc::env::init(BUILD_SCRIPT_SOURCE, - BUILD_TARGET_EXTERNAL_LIB_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_EXTERNAL_LIB_INTERMEDIATE_DIR); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_failure_states.cpp b/buildcc/lib/target/test/target/test_target_failure_states.cpp index 20a2aa74..61ea9176 100644 --- a/buildcc/lib/target/test/target/test_target_failure_states.cpp +++ b/buildcc/lib/target/test/target/test_target_failure_states.cpp @@ -294,8 +294,8 @@ TEST(TargetTestFailureStates, LinkTargetFailure_Rebuild) { } int main(int ac, char **av) { - buildcc::env::init(BUILD_SCRIPT_SOURCE, - BUILD_TARGET_FAILURE_STATES_BUILD_DIR); - fs::remove_all(buildcc::env::get_project_build_dir()); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_FAILURE_STATES_BUILD_DIR); + fs::remove_all(buildcc::Project::GetBuildDir()); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_flags.cpp b/buildcc/lib/target/test/target/test_target_flags.cpp index 5a177930..cfef234f 100644 --- a/buildcc/lib/target/test/target/test_target_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_flags.cpp @@ -646,6 +646,7 @@ TEST(TargetTestLinkFlagsGroup, Target_ChangedLinkFlag) { } int main(int ac, char **av) { - buildcc::env::init(BUILD_SCRIPT_SOURCE, BUILD_TARGET_FLAG_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_FLAG_INTERMEDIATE_DIR); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_include_dir.cpp b/buildcc/lib/target/test/target/test_target_include_dir.cpp index 91fa44b4..5f95c603 100644 --- a/buildcc/lib/target/test/target/test_target_include_dir.cpp +++ b/buildcc/lib/target/test/target/test_target_include_dir.cpp @@ -321,7 +321,7 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { } int main(int ac, char **av) { - buildcc::env::init(BUILD_SCRIPT_SOURCE, - BUILD_TARGET_INCLUDE_DIR_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_INCLUDE_DIR_INTERMEDIATE_DIR); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_lib_dep.cpp b/buildcc/lib/target/test/target/test_target_lib_dep.cpp index 5b0815da..56c97666 100644 --- a/buildcc/lib/target/test/target/test_target_lib_dep.cpp +++ b/buildcc/lib/target/test/target/test_target_lib_dep.cpp @@ -255,7 +255,7 @@ TEST(TargetTestLibDep, TargetDep_UpdateExistingLibraryTest) { } int main(int ac, char **av) { - buildcc::env::init(BUILD_SCRIPT_SOURCE, - BUILD_TARGET_LIB_DEP_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_LIB_DEP_INTERMEDIATE_DIR); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_lock.cpp b/buildcc/lib/target/test/target/test_target_lock.cpp index 3987d2c3..768db823 100644 --- a/buildcc/lib/target/test/target/test_target_lock.cpp +++ b/buildcc/lib/target/test/target/test_target_lock.cpp @@ -119,6 +119,7 @@ int main(int ac, char **av) { fs::path(BUILD_TARGET_LOCK_INTERMEDIATE_DIR) / gcc.GetName(); fs::remove_all(target_source_intermediate_path); - buildcc::env::init(BUILD_SCRIPT_SOURCE, BUILD_TARGET_LOCK_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_LOCK_INTERMEDIATE_DIR); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_pch.cpp b/buildcc/lib/target/test/target/test_target_pch.cpp index 4cfbac1f..8eefcba2 100644 --- a/buildcc/lib/target/test/target/test_target_pch.cpp +++ b/buildcc/lib/target/test/target/test_target_pch.cpp @@ -290,6 +290,7 @@ int main(int ac, char **av) { fs::path(BUILD_TARGET_PCH_INTERMEDIATE_DIR) / gcc.GetName(); fs::remove_all(target_source_intermediate_path); - buildcc::env::init(BUILD_SCRIPT_SOURCE, BUILD_TARGET_PCH_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_PCH_INTERMEDIATE_DIR); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_source.cpp b/buildcc/lib/target/test/target/test_target_source.cpp index 58c9f2d2..b94c2dfb 100644 --- a/buildcc/lib/target/test/target/test_target_source.cpp +++ b/buildcc/lib/target/test/target/test_target_source.cpp @@ -246,6 +246,7 @@ TEST(TargetTestSourceGroup, Target_CompileCommand_Throws) { } int main(int ac, char **av) { - buildcc::env::init(BUILD_SCRIPT_SOURCE, BUILD_TARGET_SOURCE_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_SOURCE_INTERMEDIATE_DIR); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp b/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp index 6491950d..b4fcac9a 100644 --- a/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp +++ b/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp @@ -87,7 +87,7 @@ TEST(TargetTestSourceOutOfRootGroup, GlobAbsolute_OutOfRootSource) { int main(int ac, char **av) { std::filesystem::create_directories(fs::path(BUILD_SCRIPT_SOURCE) / "data" / "random dir"); - buildcc::env::init(fs::path(BUILD_SCRIPT_SOURCE) / "data" / "random dir", - BUILD_TARGET_SOURCE_OUT_OF_ROOT_INTERMEDIATE_DIR); + buildcc::Project::Init(fs::path(BUILD_SCRIPT_SOURCE) / "data" / "random dir", + BUILD_TARGET_SOURCE_OUT_OF_ROOT_INTERMEDIATE_DIR); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_sync.cpp b/buildcc/lib/target/test/target/test_target_sync.cpp index cbb55d3e..8380e318 100644 --- a/buildcc/lib/target/test/target/test_target_sync.cpp +++ b/buildcc/lib/target/test/target/test_target_sync.cpp @@ -317,7 +317,8 @@ TEST(TargetTestSyncGroup, InsertCrash) { } int main(int ac, char **av) { - buildcc::env::init(BUILD_SCRIPT_SOURCE, BUILD_TARGET_SYNC_INTERMEDIATE_DIR); - fs::remove_all(buildcc::env::get_project_build_dir()); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_SYNC_INTERMEDIATE_DIR); + fs::remove_all(buildcc::Project::GetBuildDir()); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_target_user_deps.cpp b/buildcc/lib/target/test/target/test_target_user_deps.cpp index 8a4bb451..50e51c64 100644 --- a/buildcc/lib/target/test/target/test_target_user_deps.cpp +++ b/buildcc/lib/target/test/target/test_target_user_deps.cpp @@ -81,7 +81,7 @@ TEST(TargetTestUserDepsGroup, Target_Build_CompileDeps_Rebuild) { // * To make sure that save_file is newer buildcc::m::blocking_sleep(1); const fs::path new_source = - buildcc::env::get_project_root_dir() / "data" / "new_source.cpp"; + buildcc::Project::GetRootDir() / "data" / "new_source.cpp"; std::string buf{""}; buildcc::env::save_file(new_source.string().c_str(), buf, false); } @@ -120,7 +120,7 @@ TEST(TargetTestUserDepsGroup, Target_Build_LinkDeps_Rebuild) { // * To make sure that save_file is newer buildcc::m::blocking_sleep(1); const fs::path new_source = - buildcc::env::get_project_root_dir() / "data" / "new_source.cpp"; + buildcc::Project::GetRootDir() / "data" / "new_source.cpp"; std::string buf{""}; buildcc::env::save_file(new_source.string().c_str(), buf, false); } @@ -142,7 +142,7 @@ TEST(TargetTestUserDepsGroup, Target_Build_LinkDeps_Rebuild) { int main(int ac, char **av) { fs::remove_all(target_source_intermediate_path); - buildcc::env::init(BUILD_SCRIPT_SOURCE, - BUILD_TARGET_USER_DEPS_INTERMEDIATE_DIR); + buildcc::Project::Init(BUILD_SCRIPT_SOURCE, + BUILD_TARGET_USER_DEPS_INTERMEDIATE_DIR); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index 1318aefd..2ebd2423 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -54,9 +54,9 @@ struct ToolchainCompilerInfo { std::string target_arch; }; -typedef std::function( - const ToolchainExecutables &)> - ToolchainVerificationFunc; +// clang-format off +typedef std::function(const ToolchainExecutables &)> ToolchainVerificationFunc; +// clang-format on template class ToolchainVerify { public: diff --git a/buildcc/plugins/include/plugins/clang_compile_commands.h b/buildcc/plugins/include/plugins/clang_compile_commands.h index 9bfb32ee..a228e8cb 100644 --- a/buildcc/plugins/include/plugins/clang_compile_commands.h +++ b/buildcc/plugins/include/plugins/clang_compile_commands.h @@ -33,7 +33,7 @@ class ClangCompileCommands { void AddTarget(const BaseTarget *target); /** - * @brief Generate clang compile commands file in `env::get_project_build_dir` + * @brief Generate clang compile commands file in `Project::GetBuildDir` * folder */ void Generate(); diff --git a/buildcc/plugins/src/clang_compile_commands.cpp b/buildcc/plugins/src/clang_compile_commands.cpp index 6596843d..d3cd92e6 100644 --- a/buildcc/plugins/src/clang_compile_commands.cpp +++ b/buildcc/plugins/src/clang_compile_commands.cpp @@ -66,7 +66,7 @@ void ClangCompileCommands::Generate() { // DONE, Get intermediate directory from env std::string sf = fmt::format("{}", source); const std::string &command = t->GetCompileCommand(source); - std::string directory = fmt::format("{}", env::get_project_build_dir()); + std::string directory = fmt::format("{}", Project::GetBuildDir()); std::string temp = fmt::format( clang_compile_command_format, fmt::arg("directory", directory), @@ -81,7 +81,7 @@ void ClangCompileCommands::Generate() { // DONE, Convert to json // DONE, Save file std::filesystem::path file = - std::filesystem::path(buildcc::env::get_project_build_dir()) / + std::filesystem::path(buildcc::Project::GetBuildDir()) / "compile_commands.json"; bool saved = env::save_file(path_as_string(file).c_str(), compile_commands, false); diff --git a/buildexe/buildexe.cpp b/buildexe/buildexe.cpp index 5b0cc000..f9e641de 100644 --- a/buildexe/buildexe.cpp +++ b/buildexe/buildexe.cpp @@ -82,6 +82,6 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(kTag, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(kTag, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } diff --git a/buildexe/src/toolchain_setup.cpp b/buildexe/src/toolchain_setup.cpp index b007f51b..4d483daf 100644 --- a/buildexe/src/toolchain_setup.cpp +++ b/buildexe/src/toolchain_setup.cpp @@ -27,7 +27,7 @@ namespace buildcc { void host_toolchain_verify(const BaseToolchain &toolchain) { env::log_info(kTag, "*** Starting Toolchain verification ***"); - fs::path file = env::get_project_build_dir() / "verify_host_toolchain" / + fs::path file = Project::GetBuildDir() / "verify_host_toolchain" / "verify_host_toolchain.cpp"; fs::create_directories(file.parent_path()); std::string file_data = R"(// Generated by BuildExe diff --git a/docs/source/user_api/environment.rst b/docs/source/user_api/environment.rst index e353b601..9bbf4935 100644 --- a/docs/source/user_api/environment.rst +++ b/docs/source/user_api/environment.rst @@ -5,11 +5,7 @@ Environment env.h ----- -.. doxygenfunction:: is_init - -.. doxygenfunction:: get_project_root_dir - -.. doxygenfunction:: get_project_build_dir +.. doxygenclass:: buildcc::Project logging.h --------- diff --git a/docs/source/user_api/toolchain.rst b/docs/source/user_api/toolchain.rst index 4fd1b5ae..19e6bb8a 100644 --- a/docs/source/user_api/toolchain.rst +++ b/docs/source/user_api/toolchain.rst @@ -8,25 +8,79 @@ toolchain.h .. doxygentypedef:: BaseToolchain +toolchain_find.h +----------------- + +.. doxygenclass:: buildcc::ToolchainFind + +.. doxygenstruct:: buildcc::ToolchainFindConfig + toolchain_verify.h ------------------ .. doxygenclass:: buildcc::ToolchainVerify -.. doxygenstruct:: buildcc::VerifyToolchainConfig +.. doxygenstruct:: buildcc::ToolchainVerifyConfig -.. doxygenstruct:: buildcc::VerifiedToolchain +.. doxygenstruct:: buildcc::ToolchainCompilerInfo -Example --------- +Example for Default Toolchain +------------------------------ .. code-block:: cpp :linenos: - BaseToolchain custom_toolchain(ToolchainId::Custom, "custom_new_toolchain", "asm_compiler", "c_compiler", "cpp_compiler", "archiver", "linker"); + BaseToolchain arm_gcc(ToolchainId::Gcc, "arm-none-eabi-gcc", "arm-none-eabi-as", "arm-none-eabi-gcc", "arm-none-eabi-g++", "arm-none-eabi-ar", "arm-none-eabi-ld"); + + // Toolchain::Find is only used to return a list of paths where the ToolchainExecutables are found + // NOTE: All ToolchainExecutables must be found in a single directory for it to be present in the list + { + ToolchainFindConfig find_config; + // Modify it here if needed + auto found_toolchains = arm_gcc.Find(find_config); + } + + // Runs Toolchain::Find + // Selects first found toolchain (update ToolchainVerifyConfig if you want to select a different toolchain for verification) + // Runs a pre-added ToolchainId::GCC verification function + // If Verification Fails: Terminates the program + // Else: Updates the arm_gcc ToolchainExecutables to the full path + // i.e `arm-none-eabi-gcc` becomes `{host_absolute_path}/arm-none-eabi-gcc{host_executable_extension}` + { + ToolchainVerifyConfig verify_config; + // Modify it here if needed + arm_gcc.Verify(verify_config); + } + +Example for Custom Toolchain +---------------------------- + +.. code-block:: cpp + :linenos: - std::vector verified_toolchains = custom_toolchain.Verify(); - env::assert_fatal(!verified_toolchains.empty(), "Toolchain not found"); + BaseToolchain custom_toolchain(ToolchainId::Custom, "custom_new_toolchain", "assembler", "c_compiler", "cpp_compiler", "archiver", "linker"); + + // Toolchain::Find similar to previous example + + // Find all the relevant toolchains on your host system + // Selects the first found toolchain + // Runs a verification function on the selected toolchain depending on the `ToolchainId` + Toolchain::AddVerificationFunc(ToolchainId::Custom, + [](const ToolchainExecutables & executables) -> std::optional { + // Use executables to get compiler_version and target_arch + if (success) { + ToolchainCompilerInfo info; + info.compiler_version = "compiler_version"; + info.target_arch = "target_arch"; + return info; + } else { + return {}; + } + }, "custom_verification_func") + + ToolchainVerifyConfig verify_config; + verify_config.verification_identifier = "custom_verification_func"; + custom_toolchain.Verify(verify_config); Specialized Toolchain ===================== diff --git a/docs/source/user_api/toolchain_utils.rst b/docs/source/user_api/toolchain_utils.rst index 3a2976ae..6a05645f 100644 --- a/docs/source/user_api/toolchain_utils.rst +++ b/docs/source/user_api/toolchain_utils.rst @@ -18,9 +18,12 @@ toolchain_config.h .. doxygenstruct:: buildcc::ToolchainConfig -toolchain.h --------------- +toolchain_id.h +--------------- .. doxygenenum:: buildcc::ToolchainId -.. doxygenstruct:: buildcc::ToolchainBinaries +toolchain_executables.h +----------------------- + +.. doxygenstruct:: buildcc::ToolchainExecutables diff --git a/example/buildexe/libs/build.main.cpp b/example/buildexe/libs/build.main.cpp index 0159796c..b8f7d5e6 100644 --- a/example/buildexe/libs/build.main.cpp +++ b/example/buildexe/libs/build.main.cpp @@ -36,7 +36,7 @@ int main(int argc, char **argv) { StaticTarget_gcc fmt_lib( "libfmt", gcc, - TargetEnv(BuildExeLibDir::fmt, env::get_project_build_dir() / "fmt")); + TargetEnv(BuildExeLibDir::fmt, Project::GetBuildDir() / "fmt")); FmtConfig fmt_config; reg.Build(arg_gcc.state, build_fmt_cb, fmt_lib, fmt_config); @@ -64,8 +64,8 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(EXE, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(EXE, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } static void hello_world_build_cb(BaseTarget &target, BaseTarget &fmt_lib) { diff --git a/example/gcc/AfterInstall/build.cpp b/example/gcc/AfterInstall/build.cpp index 0b1cc61b..1c7a08ca 100644 --- a/example/gcc/AfterInstall/build.cpp +++ b/example/gcc/AfterInstall/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); + Project::Init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); env::set_log_level(env::LogLevel::Trace); Toolchain_gcc gcc; diff --git a/example/gcc/DynamicLib/build.cpp b/example/gcc/DynamicLib/build.cpp index 56af0976..7f7e4056 100644 --- a/example/gcc/DynamicLib/build.cpp +++ b/example/gcc/DynamicLib/build.cpp @@ -13,7 +13,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); + Project::Init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); env::set_log_level(env::LogLevel::Trace); Toolchain_gcc gcc; diff --git a/example/gcc/Flags/build.cpp b/example/gcc/Flags/build.cpp index 39401c58..01a412b6 100644 --- a/example/gcc/Flags/build.cpp +++ b/example/gcc/Flags/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); + Project::Init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); env::set_log_level(env::LogLevel::Trace); Toolchain_gcc gcc; diff --git a/example/gcc/IncludeDir/build.cpp b/example/gcc/IncludeDir/build.cpp index 4444a8d1..1a64262a 100644 --- a/example/gcc/IncludeDir/build.cpp +++ b/example/gcc/IncludeDir/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); + Project::Init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); env::set_log_level(env::LogLevel::Trace); Toolchain_gcc gcc; diff --git a/example/gcc/Plugins/build.cpp b/example/gcc/Plugins/build.cpp index 29b8da0d..1c324a56 100644 --- a/example/gcc/Plugins/build.cpp +++ b/example/gcc/Plugins/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); + Project::Init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); env::set_log_level(env::LogLevel::Trace); Toolchain_gcc gcc; diff --git a/example/gcc/Simple/build.cpp b/example/gcc/Simple/build.cpp index 8c5125f3..04686bd3 100644 --- a/example/gcc/Simple/build.cpp +++ b/example/gcc/Simple/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_SCRIPT_SOURCE, BUILD_SCRIPT_FOLDER); + Project::Init(BUILD_SCRIPT_SOURCE, BUILD_SCRIPT_FOLDER); env::set_log_level(env::LogLevel::Trace); Toolchain_gcc gcc; diff --git a/example/gcc/StaticLib/build.cpp b/example/gcc/StaticLib/build.cpp index 81c971f2..163264f8 100644 --- a/example/gcc/StaticLib/build.cpp +++ b/example/gcc/StaticLib/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); + Project::Init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); env::set_log_level(env::LogLevel::Trace); Toolchain_gcc gcc; diff --git a/example/hybrid/custom_target/build.main.cpp b/example/hybrid/custom_target/build.main.cpp index c54c8cbc..d290a117 100644 --- a/example/hybrid/custom_target/build.main.cpp +++ b/example/hybrid/custom_target/build.main.cpp @@ -57,8 +57,8 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(EXE, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(EXE, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } static void foolib_build_cb(BaseTarget &target) { diff --git a/example/hybrid/dep_chaining/build.cpp b/example/hybrid/dep_chaining/build.cpp index 4c2e007e..c2b165cb 100644 --- a/example/hybrid/dep_chaining/build.cpp +++ b/example/hybrid/dep_chaining/build.cpp @@ -86,22 +86,22 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(EXE, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(EXE, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } static void cpp_target_cb(BaseTarget &cpptarget, const BaseGenerator &cpp_generator) { const fs::path main_cpp = fs::path(cpp_generator.GetValueByIdentifier("main_cpp")) - .lexically_relative(env::get_project_root_dir()); + .lexically_relative(Project::GetRootDir()); cpptarget.AddSource(main_cpp); cpptarget.Build(); } static void c_target_cb(BaseTarget &ctarget, const BaseGenerator &c_generator) { const fs::path main_c = fs::path(c_generator.GetValueByIdentifier("main_c")) - .lexically_relative(env::get_project_root_dir()); + .lexically_relative(Project::GetRootDir()); ctarget.AddSource(main_c); ctarget.Build(); } diff --git a/example/hybrid/external_lib/build.main.cpp b/example/hybrid/external_lib/build.main.cpp index f2e1cfa7..b32cb01a 100644 --- a/example/hybrid/external_lib/build.main.cpp +++ b/example/hybrid/external_lib/build.main.cpp @@ -44,8 +44,8 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(EXE, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(EXE, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } static void foolib_build_cb(BaseTarget &target) { diff --git a/example/hybrid/foolib/build.main.cpp b/example/hybrid/foolib/build.main.cpp index 66e618be..3586f275 100644 --- a/example/hybrid/foolib/build.main.cpp +++ b/example/hybrid/foolib/build.main.cpp @@ -44,8 +44,8 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(EXE, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(EXE, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } static void foolib_build_cb(BaseTarget &target) { diff --git a/example/hybrid/generic/build.cpp b/example/hybrid/generic/build.cpp index bcf89acf..605ed4a0 100644 --- a/example/hybrid/generic/build.cpp +++ b/example/hybrid/generic/build.cpp @@ -115,12 +115,12 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(EXE, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(EXE, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } static void foolib_build_cb(BaseTarget &foolib_target) { - fooTarget(foolib_target, env::get_project_root_dir() / ".." / "foolib"); + fooTarget(foolib_target, Project::GetRootDir() / ".." / "foolib"); foolib_target.Build(); } diff --git a/example/hybrid/pch/build.cpp b/example/hybrid/pch/build.cpp index 1c12a502..8f7bc63d 100644 --- a/example/hybrid/pch/build.cpp +++ b/example/hybrid/pch/build.cpp @@ -69,8 +69,8 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(EXE, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(EXE, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } static void cppflags_build_cb(BaseTarget &cppflags) { diff --git a/example/hybrid/simple/build.cpp b/example/hybrid/simple/build.cpp index 963d3333..ec4d5d80 100644 --- a/example/hybrid/simple/build.cpp +++ b/example/hybrid/simple/build.cpp @@ -69,8 +69,8 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(EXE, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(EXE, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } static void cppflags_build_cb(BaseTarget &cppflags) { diff --git a/example/hybrid/single/build.cpp b/example/hybrid/single/build.cpp index b8b104d5..6ab78d85 100644 --- a/example/hybrid/single/build.cpp +++ b/example/hybrid/single/build.cpp @@ -48,8 +48,8 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(EXE, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(EXE, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } static void hello_world_build_cb(BaseTarget &target) { diff --git a/example/hybrid/target_info/build.cpp b/example/hybrid/target_info/build.cpp index 3fb2cf26..f4926d01 100644 --- a/example/hybrid/target_info/build.cpp +++ b/example/hybrid/target_info/build.cpp @@ -83,8 +83,8 @@ int main(int argc, char **argv) { } static void clean_cb() { - env::log_info(EXE, fmt::format("Cleaning {}", env::get_project_build_dir())); - fs::remove_all(env::get_project_build_dir()); + env::log_info(EXE, fmt::format("Cleaning {}", Project::GetBuildDir())); + fs::remove_all(Project::GetBuildDir()); } static void genericadd_ho_cb(TargetInfo &genericadd_ho) { diff --git a/example/mingw/DynamicLib/build.cpp b/example/mingw/DynamicLib/build.cpp index 5a166e31..1de9c662 100644 --- a/example/mingw/DynamicLib/build.cpp +++ b/example/mingw/DynamicLib/build.cpp @@ -13,7 +13,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); + Project::Init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); env::set_log_level(env::LogLevel::Trace); Toolchain_mingw mingw; diff --git a/example/mingw/Executable/build.cpp b/example/mingw/Executable/build.cpp index 07ac8279..41550319 100644 --- a/example/mingw/Executable/build.cpp +++ b/example/mingw/Executable/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); + Project::Init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); env::set_log_level(env::LogLevel::Trace); Toolchain_mingw mingw; diff --git a/example/mingw/Pch/build.cpp b/example/mingw/Pch/build.cpp index c09973fc..c4747467 100644 --- a/example/mingw/Pch/build.cpp +++ b/example/mingw/Pch/build.cpp @@ -15,7 +15,7 @@ int main() { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); + Project::Init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); env::set_log_level(env::LogLevel::Trace); Toolchain_mingw mingw; diff --git a/example/mingw/StaticLib/build.cpp b/example/mingw/StaticLib/build.cpp index ce21b845..628d5081 100644 --- a/example/mingw/StaticLib/build.cpp +++ b/example/mingw/StaticLib/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); + Project::Init(BUILD_ROOT, BUILD_INTERMEDIATE_DIR); env::set_log_level(env::LogLevel::Trace); Toolchain_mingw mingw; diff --git a/example/msvc/DynamicLib/build.cpp b/example/msvc/DynamicLib/build.cpp index 65d5b9d6..7c20a2f9 100644 --- a/example/msvc/DynamicLib/build.cpp +++ b/example/msvc/DynamicLib/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_SCRIPT_SOURCE, BUILD_SCRIPT_FOLDER); + Project::Init(BUILD_SCRIPT_SOURCE, BUILD_SCRIPT_FOLDER); env::set_log_level(env::LogLevel::Debug); Toolchain_msvc msvc; diff --git a/example/msvc/Executable/build.cpp b/example/msvc/Executable/build.cpp index 9d83d8bb..8ea7d4c9 100644 --- a/example/msvc/Executable/build.cpp +++ b/example/msvc/Executable/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_SCRIPT_SOURCE, BUILD_SCRIPT_FOLDER); + Project::Init(BUILD_SCRIPT_SOURCE, BUILD_SCRIPT_FOLDER); env::set_log_level(env::LogLevel::Trace); Toolchain_msvc msvc; diff --git a/example/msvc/StaticLib/build.cpp b/example/msvc/StaticLib/build.cpp index 7622c2b7..5410df18 100644 --- a/example/msvc/StaticLib/build.cpp +++ b/example/msvc/StaticLib/build.cpp @@ -12,7 +12,7 @@ int main(void) { // this path // 2. Intermediate build folder i.e all intermediate generated files should go // here - env::init(BUILD_SCRIPT_SOURCE, BUILD_SCRIPT_FOLDER); + Project::Init(BUILD_SCRIPT_SOURCE, BUILD_SCRIPT_FOLDER); env::set_log_level(env::LogLevel::Trace); Toolchain_msvc msvc; From 94d62c90b564469f2094bc3cc0a2b0fc694fe632 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 27 Mar 2022 20:05:21 -0700 Subject: [PATCH 10/35] Refactor `Args` constructable class to static class (#202) --- bootstrap/main.buildcc.cpp | 9 +- buildcc/lib/args/CMakeLists.txt | 1 + buildcc/lib/args/include/args/args.h | 45 ++-- buildcc/lib/args/include/args/register.h | 5 +- buildcc/lib/args/mock/parse.cpp | 2 +- buildcc/lib/args/src/args.cpp | 60 +++++- buildcc/lib/args/src/parse.cpp | 4 +- buildcc/lib/args/src/register.cpp | 8 +- buildcc/lib/args/test/test_args.cpp | 113 +++++----- buildcc/lib/args/test/test_register.cpp | 215 ++++++++++---------- buildcc/lib/env/include/env/env.h | 3 + buildexe/buildexe.cpp | 2 +- buildexe/include/buildexe/args_setup.h | 4 +- buildexe/src/args_setup.cpp | 13 +- example/buildexe/libs/build.main.cpp | 9 +- example/hybrid/custom_target/build.main.cpp | 14 +- example/hybrid/dep_chaining/build.cpp | 10 +- example/hybrid/external_lib/build.main.cpp | 10 +- example/hybrid/foolib/build.main.cpp | 10 +- example/hybrid/generic/CMakeLists.txt | 2 - example/hybrid/generic/build.cpp | 10 +- example/hybrid/pch/build.cpp | 10 +- example/hybrid/simple/build.cpp | 10 +- example/hybrid/single/build.cpp | 8 +- example/hybrid/target_info/build.cpp | 10 +- 25 files changed, 318 insertions(+), 269 deletions(-) diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index 7f08c37b..4882d013 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -33,12 +33,13 @@ static void hybrid_simple_example_cb(BaseTarget &target, const BaseTarget &libbuildcc); int main(int argc, char **argv) { - Args args; + Args::Init(); ArgToolchain custom_toolchain_arg; - args.AddToolchain("host", "Host Toolchain", custom_toolchain_arg); - args.Parse(argc, argv); + Args::AddToolchain("host", "Host Toolchain", custom_toolchain_arg); + Args::Parse(argc, argv); - Register reg(args); + Register reg; + ; reg.Clean(clean_cb); BaseToolchain toolchain = custom_toolchain_arg.ConstructToolchain(); diff --git a/buildcc/lib/args/CMakeLists.txt b/buildcc/lib/args/CMakeLists.txt index ffc289fa..5b5843fa 100644 --- a/buildcc/lib/args/CMakeLists.txt +++ b/buildcc/lib/args/CMakeLists.txt @@ -8,6 +8,7 @@ add_library(mock_args ) target_include_directories(mock_args PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/mock ) target_compile_options(mock_args PUBLIC ${TEST_COMPILE_FLAGS} ${BUILD_COMPILE_FLAGS} diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index c687df92..a8b43d51 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -88,8 +88,12 @@ struct ArgTarget { class Args { public: public: - Args() { Initialize(); } + Args() = delete; Args(const Args &) = delete; + Args(Args &&) = delete; + + static void Init(); + static void Deinit(); /** * @brief Parse command line information to CLI11 @@ -97,17 +101,17 @@ class Args { * @param argc from int main(int argc, char ** argv) * @param argv from int main(int argc, char ** argv) */ - void Parse(int argc, const char *const *argv); + static void Parse(int argc, const char *const *argv); /** * @brief Modifiable reference to CLI::App (CLI11) */ - CLI::App &Ref() { return app_; } + static CLI::App &Ref(); /** * @brief Constant reference to CLI::App (CLI11) */ - const CLI::App &ConstRef() const { return app_; } + static const CLI::App &ConstRef(); // Setters @@ -117,9 +121,9 @@ class Args { * @param out Receive the toolchain information through the CLI * @param initial Set the default toolchain information as a fallback */ - void AddToolchain(const std::string &name, const std::string &description, - ArgToolchain &out, - const ArgToolchain &initial = ArgToolchain()); + static void AddToolchain(const std::string &name, + const std::string &description, ArgToolchain &out, + const ArgToolchain &initial = ArgToolchain()); /** * @brief Add Target config commands with a unique name and description @@ -129,31 +133,18 @@ class Args { * * TODO, Update with other options for TargetConfig */ - void AddTarget(const std::string &name, const std::string &description, - ArgTarget &out, const ArgTarget &initial = ArgTarget()); + static void AddTarget(const std::string &name, const std::string &description, + ArgTarget &out, const ArgTarget &initial = ArgTarget()); // Getters - bool Clean() const { return clean_; } - env::LogLevel GetLogLevel() const { return loglevel_; } - - const fs::path &GetProjectRootDir() const { return project_root_dir_; } - const fs::path &GetProjectBuildDir() const { return project_build_dir_; } + static bool Clean(); + static env::LogLevel GetLogLevel(); -private: - void Initialize(); - void RootArgs(); + static const fs::path &GetProjectRootDir(); + static const fs::path &GetProjectBuildDir(); private: - // Required parameters - bool clean_{false}; - env::LogLevel loglevel_{env::LogLevel::Info}; - fs::path project_root_dir_{""}; - fs::path project_build_dir_{"_internal"}; - - // Internal - CLI::App app_{"BuildCC buildsystem"}; - CLI::App *toolchain_{nullptr}; - CLI::App *target_{nullptr}; + static void RootArgs(); }; } // namespace buildcc diff --git a/buildcc/lib/args/include/args/register.h b/buildcc/lib/args/include/args/register.h index 04210789..c15a0b83 100644 --- a/buildcc/lib/args/include/args/register.h +++ b/buildcc/lib/args/include/args/register.h @@ -33,7 +33,8 @@ namespace buildcc { class Register { public: - Register(const Args &args) : args_(args) { Initialize(); } + // Register(const Args &args) : args_(args) { Initialize(); } + Register() { Initialize(); } Register(const Register &) = delete; /** @@ -154,7 +155,7 @@ class Register { void BuildStoreTask(const std::string &unique_id, const tf::Task &task); private: - const Args &args_; + // const Args &args_; // Build tf::Taskflow build_tf_{"Targets"}; diff --git a/buildcc/lib/args/mock/parse.cpp b/buildcc/lib/args/mock/parse.cpp index 210a7530..dcbccc3c 100644 --- a/buildcc/lib/args/mock/parse.cpp +++ b/buildcc/lib/args/mock/parse.cpp @@ -6,7 +6,7 @@ namespace buildcc { void Args::Parse(int argc, const char *const *argv) { try { - app_.parse(argc, argv); + Ref().parse(argc, argv); } catch (const CLI::ParseError &e) { env::assert_fatal(e.what()); } diff --git a/buildcc/lib/args/src/args.cpp b/buildcc/lib/args/src/args.cpp index e6cd76a1..ec6b4a33 100644 --- a/buildcc/lib/args/src/args.cpp +++ b/buildcc/lib/args/src/args.cpp @@ -84,12 +84,56 @@ const std::unordered_map kToolchainIdMap{ {"undefined", buildcc::ToolchainId::Undefined}, }; +// Static variables +bool clean_{false}; +buildcc::env::LogLevel loglevel_{buildcc::env::LogLevel::Info}; +fs::path project_root_dir_{""}; +fs::path project_build_dir_{"_internal"}; + +// Internal +// std::unique_ptr app_; +// CLI::App *toolchain_{nullptr}; +// CLI::App *target_{nullptr}; + +struct ArgsInstance { + CLI::App app_{"BuildCC Buildsystem"}; + CLI::App *toolchain_{nullptr}; + CLI::App *target_{nullptr}; +}; + +std::unique_ptr args_instance_; + } // namespace namespace buildcc { +void Args::Init() { + if (!args_instance_) { + args_instance_ = std::make_unique(); + args_instance_->toolchain_ = + Ref().add_subcommand(kToolchainSubcommand, kToolchainDesc); + args_instance_->target_ = + Ref().add_subcommand(kTargetSubcommand, kTargetDesc); + RootArgs(); + } +} + +void Args::Deinit() { args_instance_.reset(nullptr); } + +CLI::App &Args::Ref() { return args_instance_->app_; } +const CLI::App &Args::ConstRef() { return args_instance_->app_; } + +bool Args::Clean() { return clean_; } +env::LogLevel Args::GetLogLevel() { return loglevel_; } + +const fs::path &Args::GetProjectRootDir() { return project_root_dir_; } +const fs::path &Args::GetProjectBuildDir() { return project_build_dir_; } + void Args::AddToolchain(const std::string &name, const std::string &description, ArgToolchain &out, const ArgToolchain &initial) { + CLI::App *toolchain_ = args_instance_->toolchain_; + env::assert_fatal(toolchain_ != nullptr, + "Initialize Args using the Args::Init API"); CLI::App *t_user = toolchain_->add_subcommand(name, description)->group(kToolchainGroup); t_user->add_flag(kToolchainBuildParam, out.state.build); @@ -113,6 +157,9 @@ void Args::AddToolchain(const std::string &name, const std::string &description, void Args::AddTarget(const std::string &name, const std::string &description, ArgTarget &out, const ArgTarget &initial) { + CLI::App *target_ = args_instance_->target_; + env::assert_fatal(target_ != nullptr, + "Initialize Args using the Args::Init API"); CLI::App *target_user = target_->add_subcommand(name, description)->group(kTargetGroup); target_user->add_option(kTargetCompileCommandParam, out.compile_command) @@ -123,20 +170,15 @@ void Args::AddTarget(const std::string &name, const std::string &description, // Private -void Args::Initialize() { - RootArgs(); - toolchain_ = app_.add_subcommand(kToolchainSubcommand, kToolchainDesc); - target_ = app_.add_subcommand(kTargetSubcommand, kTargetDesc); -} - void Args::RootArgs() { - app_.set_help_all_flag(kHelpAllParam, kHelpAllDesc); + Ref().set_help_all_flag(kHelpAllParam, kHelpAllDesc); - app_.set_config(kConfigParam, "", kConfigDesc) + Ref() + .set_config(kConfigParam, "", kConfigDesc) ->expected(kMinFiles, kMaxFiles); // Root flags - auto *root_group = app_.add_option_group(kRootGroup); + auto *root_group = Ref().add_option_group(kRootGroup); root_group->add_flag(kCleanParam, clean_, kCleanDesc); root_group->add_option(kLoglevelParam, loglevel_, kLoglevelDesc) diff --git a/buildcc/lib/args/src/parse.cpp b/buildcc/lib/args/src/parse.cpp index 637ee6f4..08baac2f 100644 --- a/buildcc/lib/args/src/parse.cpp +++ b/buildcc/lib/args/src/parse.cpp @@ -20,9 +20,9 @@ namespace buildcc { void Args::Parse(int argc, const char *const *argv) { try { - app_.parse(argc, argv); + Ref().parse(argc, argv); } catch (const CLI::ParseError &e) { - exit(app_.exit(e)); + exit(ConstRef().exit(e)); } } diff --git a/buildcc/lib/args/src/register.cpp b/buildcc/lib/args/src/register.cpp index 680071d8..cbd1e719 100644 --- a/buildcc/lib/args/src/register.cpp +++ b/buildcc/lib/args/src/register.cpp @@ -61,7 +61,7 @@ void DepDetectCyclicDependency(const tf::Task &target_task, namespace buildcc { void Register::Clean(const std::function &clean_cb) { - if (args_.Clean()) { + if (Args::Clean()) { clean_cb(); } } @@ -119,9 +119,9 @@ void Register::BuildStoreTask(const std::string &unique_id, void Register::Initialize() { Env(); } void Register::Env() { - Project::Init(fs::current_path() / args_.GetProjectRootDir(), - fs::current_path() / args_.GetProjectBuildDir()); - env::set_log_level(args_.GetLogLevel()); + Project::Init(fs::current_path() / Args::GetProjectRootDir(), + fs::current_path() / Args::GetProjectBuildDir()); + env::set_log_level(Args::GetLogLevel()); } // diff --git a/buildcc/lib/args/test/test_args.cpp b/buildcc/lib/args/test/test_args.cpp index acaa82b7..8c4c3979 100644 --- a/buildcc/lib/args/test/test_args.cpp +++ b/buildcc/lib/args/test/test_args.cpp @@ -9,29 +9,37 @@ // clang-format off TEST_GROUP(ArgsTestGroup) { + void teardown() { + buildcc::Args::Deinit(); + } }; // clang-format on TEST(ArgsTestGroup, Args_BasicParse) { + UT_PRINT("Args_BasicParse\r\n"); std::vector av{"", "--config", "configs/basic_parse.toml"}; int argc = av.size(); - buildcc::Args args; - args.Parse(argc, av.data()); + buildcc::Args::Init(); + buildcc::Args::Init(); // Second init does nothing when already initialized + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); + buildcc::Args::Ref().name("new_name"); + STRCMP_EQUAL(buildcc::Args::Ref().get_name().c_str(), "new_name"); } TEST(ArgsTestGroup, Args_BasicExit) { + UT_PRINT("Args_BasicExit\r\n"); std::vector av{"", "--config", "configs/basic_parse.toml", "--help"}; int argc = av.size(); - buildcc::Args args; - CHECK_THROWS(std::exception, args.Parse(argc, av.data())); + buildcc::Args::Init(); + CHECK_THROWS(std::exception, buildcc::Args::Parse(argc, av.data())); } TEST(ArgsTestGroup, Args_MultiToml) { @@ -39,13 +47,13 @@ TEST(ArgsTestGroup, Args_MultiToml) { "--config", "configs/no_clean.toml"}; int argc = av.size(); - buildcc::Args args; - args.Parse(argc, av.data()); + buildcc::Args::Init(); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_FALSE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_FALSE(buildcc::Args::Clean()); } TEST(ArgsTestGroup, Args_CustomToolchain) { @@ -53,15 +61,15 @@ TEST(ArgsTestGroup, Args_CustomToolchain) { "--config", "configs/gcc_toolchain.toml"}; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // Toolchain CHECK_TRUE(gcc_toolchain.state.build); @@ -87,17 +95,17 @@ TEST(ArgsTestGroup, Args_MultipleCustomToolchain) { }; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // Toolchain @@ -125,17 +133,18 @@ TEST(ArgsTestGroup, Args_MultipleCustomToolchain) { } TEST(ArgsTestGroup, Args_DuplicateCustomToolchain) { - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain other_gcc_toolchain; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); // CLI11 Throws an exception when multiple toolchains with same name are added // NOTE, This behaviour does not need to be tested since it is provided by // CLI11 // This test is as an example of wrong usage by the user - CHECK_THROWS(std::exception, args.AddToolchain("gcc", "Other gcc toolchain", - other_gcc_toolchain)); + CHECK_THROWS(std::exception, + (buildcc::Args::AddToolchain("gcc", "Other gcc toolchain ", + other_gcc_toolchain))); } TEST(ArgsTestGroup, Args_CustomTarget) { @@ -150,17 +159,17 @@ TEST(ArgsTestGroup, Args_CustomTarget) { }; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgTarget gcc_target; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.AddTarget("gcc", "Generic gcc target", gcc_target); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddTarget("gcc", "Generic gcc target", gcc_target); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // Toolchain CHECK_TRUE(gcc_toolchain.state.build); @@ -198,21 +207,21 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { }; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgTarget gcc_target; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.AddTarget("gcc", "Generic gcc target", gcc_target); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddTarget("gcc", "Generic gcc target", gcc_target); buildcc::ArgToolchain msvc_toolchain; buildcc::ArgTarget msvc_target; - args.AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - args.AddTarget("msvc", "Generic msvc target", msvc_target); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); + buildcc::Args::AddTarget("msvc", "Generic msvc target", msvc_target); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // GCC @@ -258,6 +267,6 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { } int main(int ac, char **av) { - MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); + MemoryLeakWarningPlugin::destroyGlobalDetector(); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/args/test/test_register.cpp b/buildcc/lib/args/test/test_register.cpp index 948ba972..81dbd9cf 100644 --- a/buildcc/lib/args/test/test_register.cpp +++ b/buildcc/lib/args/test/test_register.cpp @@ -14,9 +14,10 @@ // clang-format off TEST_GROUP(RegisterTestGroup) { - void teardown() { - mock().clear(); - } + void teardown() { + buildcc::Args::Deinit(); + mock().clear(); + } }; // clang-format on @@ -24,15 +25,15 @@ TEST(RegisterTestGroup, Register_Initialize) { std::vector av{"", "--config", "configs/basic_parse.toml"}; int argc = av.size(); - buildcc::Args args; - args.Parse(argc, av.data()); + buildcc::Args::Init(); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); - buildcc::Register reg(args); + buildcc::Register reg; } TEST(RegisterTestGroup, Register_Clean) { @@ -40,17 +41,18 @@ TEST(RegisterTestGroup, Register_Clean) { std::vector av{"", "--config", "configs/basic_parse.toml"}; int argc = av.size(); - buildcc::Args args; - args.Parse(argc, av.data()); + buildcc::Args::Init(); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); - buildcc::Register reg(args); + buildcc::Register reg; mock().expectOneCall("CleanCb"); reg.Clean([]() { mock().actualCall("CleanCb"); }); + buildcc::Args::Deinit(); } { @@ -63,16 +65,17 @@ TEST(RegisterTestGroup, Register_Clean) { }; int argc = av.size(); - buildcc::Args args; - args.Parse(argc, av.data()); + buildcc::Args::Init(); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_FALSE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_FALSE(buildcc::Args::Clean()); - buildcc::Register reg(args); + buildcc::Register reg; reg.Clean([]() { mock().actualCall("CleanCb"); }); + buildcc::Args::Deinit(); } mock().checkExpectations(); @@ -86,17 +89,17 @@ TEST(RegisterTestGroup, Register_Build) { }; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); @@ -108,7 +111,7 @@ TEST(RegisterTestGroup, Register_Build) { { buildcc::ArgToolchainState state{false, false}; - buildcc::Register reg(args); + buildcc::Register reg; reg.Build( state, [](buildcc::BaseTarget &target) { (void)target; }, target); } @@ -116,7 +119,7 @@ TEST(RegisterTestGroup, Register_Build) { { buildcc::ArgToolchainState state{true, true}; - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); reg.Build( state, [](buildcc::BaseTarget &target) { (void)target; }, target); @@ -134,17 +137,17 @@ TEST(RegisterTestGroup, Register_NoBuildAndDep) { }; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); @@ -167,13 +170,13 @@ TEST(RegisterTestGroup, Register_NoBuildAndDep) { // T0D0 { - buildcc::Register reg(args); + buildcc::Register reg; CHECK_THROWS(std::exception, reg.Dep(target, dependency)); } // T0D1 { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_depT"); reg.Build( trueState, [](buildcc::BaseTarget &target) { (void)target; }, @@ -184,7 +187,7 @@ TEST(RegisterTestGroup, Register_NoBuildAndDep) { // T1D0 { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); reg.Build( trueState, [](buildcc::BaseTarget &target) { (void)target; }, target); @@ -194,7 +197,7 @@ TEST(RegisterTestGroup, Register_NoBuildAndDep) { // T1D1 { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); reg.Build( @@ -218,17 +221,17 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { }; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); @@ -251,7 +254,7 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { // T0D0 { - buildcc::Register reg(args); + buildcc::Register reg; reg.Build( falseState, [](buildcc::BaseTarget &target) { (void)target; }, target); reg.Build( @@ -263,7 +266,7 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { // T0D1 { - buildcc::Register reg(args); + buildcc::Register reg; reg.Build( falseState, [](buildcc::BaseTarget &target) { (void)target; }, target); mock().expectNCalls(1, "BuildTask_depT"); @@ -276,7 +279,7 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { // T1D0 { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); reg.Build( trueState, [](buildcc::BaseTarget &target) { (void)target; }, target); @@ -289,7 +292,7 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { // T1D1 { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); reg.Build( @@ -313,17 +316,17 @@ TEST(RegisterTestGroup, Register_DepDuplicate) { }; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); @@ -340,7 +343,7 @@ TEST(RegisterTestGroup, Register_DepDuplicate) { // Duplicate dependency with 2 Targets { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); reg.Build( @@ -355,7 +358,7 @@ TEST(RegisterTestGroup, Register_DepDuplicate) { // Duplicate dependency with 3 Targets { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); mock().expectNCalls(1, "BuildTask_dep2T"); @@ -389,17 +392,17 @@ TEST(RegisterTestGroup, Register_DepCyclic) { }; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); @@ -416,7 +419,7 @@ TEST(RegisterTestGroup, Register_DepCyclic) { // Immediate cyclic depdendency { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); reg.Build( @@ -431,7 +434,7 @@ TEST(RegisterTestGroup, Register_DepCyclic) { // Duplicate dependency with 3 Targets { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); mock().expectNCalls(1, "BuildTask_dep2T"); @@ -465,17 +468,17 @@ TEST(RegisterTestGroup, Register_Test) { }; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); @@ -498,33 +501,33 @@ TEST(RegisterTestGroup, Register_Test) { // FF { - buildcc::Register reg(args); + buildcc::Register reg; reg.Test(stateFail, "{executable}", target); } // TF { - buildcc::Register reg(args); + buildcc::Register reg; reg.Test(state1, "{executable}", target); } // FT { - buildcc::Register reg(args); + buildcc::Register reg; reg.Test(state2, "{executable}", target); } // TT // Register::Build not called { - buildcc::Register reg(args); + buildcc::Register reg; CHECK_THROWS(std::exception, reg.Test(stateSuccess, "{executable}", target)); } // Correct Usage { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); reg.Build( stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, @@ -550,17 +553,17 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { }; int argc = av.size(); - buildcc::Args args; + buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - args.AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - args.AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - args.Parse(argc, av.data()); + buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); + buildcc::Args::Parse(argc, av.data()); - STRCMP_EQUAL(args.GetProjectRootDir().string().c_str(), "root"); - STRCMP_EQUAL(args.GetProjectBuildDir().string().c_str(), "build"); - CHECK(args.GetLogLevel() == buildcc::env::LogLevel::Trace); - CHECK_TRUE(args.Clean()); + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); @@ -575,7 +578,7 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { // TestOutput::Type::DefaultBehaviour { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); reg.Build( stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, @@ -592,7 +595,7 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { // TestOutput::Type::TestPrintOnStderr { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); reg.Build( stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, @@ -610,7 +613,7 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { // TestOutput::Type::TestPrintOnStdout { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); reg.Build( stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, @@ -628,7 +631,7 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { // TestOutput::Type::TestPrintOnStderrAndStdout { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); reg.Build( stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, @@ -647,7 +650,7 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { // TestOutput::Type::UserRedirect { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); reg.Build( stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, @@ -664,7 +667,7 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { // TestOutput::Type::UserRedirect { - buildcc::Register reg(args); + buildcc::Register reg; mock().expectNCalls(1, "BuildTask_dummyT"); reg.Build( stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, @@ -681,7 +684,7 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { } int main(int ac, char **av) { - MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); + MemoryLeakWarningPlugin::destroyGlobalDetector(); buildcc::env::m::VectorStringCopier copier; mock().installCopier(TEST_VECTOR_STRING_TYPE, copier); return CommandLineTestRunner::RunAllTests(ac, av); diff --git a/buildcc/lib/env/include/env/env.h b/buildcc/lib/env/include/env/env.h index e9b9fb78..c260b28c 100644 --- a/buildcc/lib/env/include/env/env.h +++ b/buildcc/lib/env/include/env/env.h @@ -27,6 +27,9 @@ namespace buildcc { class Project { public: + Project() = delete; + Project(const Project &) = delete; + Project(Project &&) = delete; static void Init(const fs::path &project_root_dir, const fs::path &project_build_dir); static void Deinit(); diff --git a/buildexe/buildexe.cpp b/buildexe/buildexe.cpp index f9e641de..7077d8dd 100644 --- a/buildexe/buildexe.cpp +++ b/buildexe/buildexe.cpp @@ -54,7 +54,7 @@ int main(int argc, char **argv) { // TODO, Add libraries (git cloned) // TODO, Add extension (git cloned) - Register reg(buildexe_args.GetArgs()); + Register reg; reg.Clean(clean_cb); // Host Toolchain diff --git a/buildexe/include/buildexe/args_setup.h b/buildexe/include/buildexe/args_setup.h index 5fc9faff..26419a53 100644 --- a/buildexe/include/buildexe/args_setup.h +++ b/buildexe/include/buildexe/args_setup.h @@ -62,10 +62,9 @@ struct LibInfo { class BuildExeArgs { public: void Setup(); - void Parse(int argc, char **argv) { args_.Parse(argc, argv); } + void Parse(int argc, char **argv) { Args::Parse(argc, argv); } // Getters - const Args &GetArgs() const { return args_; } const ArgToolchain &GetHostToolchainArg() const { return host_toolchain_arg_; } @@ -87,7 +86,6 @@ class BuildExeArgs { void SetupLibs(); private: - Args args_; ArgToolchain host_toolchain_arg_; ArgTargetInfo out_targetinfo_; ArgTargetInputs out_targetinputs_; diff --git a/buildexe/src/args_setup.cpp b/buildexe/src/args_setup.cpp index a797bf95..3ec0fb4f 100644 --- a/buildexe/src/args_setup.cpp +++ b/buildexe/src/args_setup.cpp @@ -33,7 +33,8 @@ static const std::unordered_map kTargetTypeMap{ }; void BuildExeArgs::Setup() { - args_.AddToolchain("host", "Host Toolchain", host_toolchain_arg_); + Args::Init(); + Args::AddToolchain("host", "Host Toolchain", host_toolchain_arg_); SetupBuildMode(); SetupTargetInfo(); SetupTargetInputs(); @@ -42,7 +43,7 @@ void BuildExeArgs::Setup() { } void BuildExeArgs::SetupBuildMode() { - args_.Ref() + Args::Ref() .add_option("--mode", out_mode_, "Provide BuildExe run mode") ->transform(CLI::CheckedTransformer(kBuildExeModeMap, CLI::ignore_case)) ->required(); @@ -51,7 +52,7 @@ void BuildExeArgs::SetupBuildMode() { // TODO, Add subcommand [build.info] void BuildExeArgs::SetupTargetInfo() { constexpr const char *const kProjectInfo = "Project Info"; - auto &app = args_.Ref(); + auto &app = Args::Ref(); auto *project_info_app = app.add_option_group(kProjectInfo); @@ -74,7 +75,7 @@ void BuildExeArgs::SetupTargetInfo() { // TODO, Add group, group by sources, headers, inncludes on CLI void BuildExeArgs::SetupTargetInputs() { constexpr const char *const kTargetInputs = "Target Inputs"; - auto &app = args_.Ref(); + auto &app = Args::Ref(); auto *target_inputs_app = app.add_option_group(kTargetInputs); @@ -109,13 +110,13 @@ void BuildExeArgs::SetupTargetInputs() { } void BuildExeArgs::SetupScriptMode() { - auto *script_args = args_.Ref().add_subcommand("script"); + auto *script_args = Args::Ref().add_subcommand("script"); script_args->add_option("--configs", out_scriptinfo_.configs, "Config files for script mode"); } void BuildExeArgs::SetupLibs() { - auto *libs_app = args_.Ref().add_subcommand("libs", "Libraries"); + auto *libs_app = Args::Ref().add_subcommand("libs", "Libraries"); std::error_code ec; fs::directory_iterator dir_iter = fs::directory_iterator(BuildccHome::GetBuildccLibsDir(), ec); diff --git a/example/buildexe/libs/build.main.cpp b/example/buildexe/libs/build.main.cpp index b8f7d5e6..5937c5ee 100644 --- a/example/buildexe/libs/build.main.cpp +++ b/example/buildexe/libs/build.main.cpp @@ -17,13 +17,14 @@ static void hello_world_build_cb(BaseTarget &target, BaseTarget &fmt_lib); int main(int argc, char **argv) { // 1. Get arguments - Args args; + Args::Init(); ArgToolchain arg_gcc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.Parse(argc, argv); + Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); + Args::Parse(argc, argv); // 2. Initialize your environment - Register reg(args); + Register reg; + ; // 3. Pre-build steps reg.Clean(clean_cb); diff --git a/example/hybrid/custom_target/build.main.cpp b/example/hybrid/custom_target/build.main.cpp index d290a117..50390bd3 100644 --- a/example/hybrid/custom_target/build.main.cpp +++ b/example/hybrid/custom_target/build.main.cpp @@ -9,19 +9,19 @@ static constexpr std::string_view EXE = "build"; int main(int argc, char **argv) { // 1. Get arguments - Args args; + Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; ArgToolchain toolchain_clang_gnu; ArgTarget target_clang_gnu; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - args.AddToolchain("clang_gnu", "Clang GNU toolchain", toolchain_clang_gnu); - args.AddTarget("clang_gnu", "Clang GNU target", target_clang_gnu); - args.Parse(argc, argv); + Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); + Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); + Args::AddToolchain("clang_gnu", "Clang GNU toolchain", toolchain_clang_gnu); + Args::AddTarget("clang_gnu", "Clang GNU target", target_clang_gnu); + Args::Parse(argc, argv); // 2. Initialize your environment - Register reg(args); + Register reg; // 3. Pre-build steps reg.Clean(clean_cb); diff --git a/example/hybrid/dep_chaining/build.cpp b/example/hybrid/dep_chaining/build.cpp index c2b165cb..915507bd 100644 --- a/example/hybrid/dep_chaining/build.cpp +++ b/example/hybrid/dep_chaining/build.cpp @@ -16,15 +16,15 @@ static void c_generator_cb(BaseGenerator &generator); int main(int argc, char **argv) { // 1. Get arguments - Args args; + Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - args.Parse(argc, argv); + Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); + Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); + Args::Parse(argc, argv); // 2. Initialize your environment - Register reg(args); + Register reg; // 3. Pre-build steps reg.Clean(clean_cb); diff --git a/example/hybrid/external_lib/build.main.cpp b/example/hybrid/external_lib/build.main.cpp index b32cb01a..fd56b11f 100644 --- a/example/hybrid/external_lib/build.main.cpp +++ b/example/hybrid/external_lib/build.main.cpp @@ -11,15 +11,15 @@ constexpr const char *const EXE = "build"; int main(int argc, char **argv) { // 1. Get arguments - Args args; + Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - args.Parse(argc, argv); + Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); + Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); + Args::Parse(argc, argv); // 2. Initialize your environment - Register reg(args); + Register reg; // 3. Pre-build steps reg.Clean(clean_cb); diff --git a/example/hybrid/foolib/build.main.cpp b/example/hybrid/foolib/build.main.cpp index 3586f275..bbd3eba6 100644 --- a/example/hybrid/foolib/build.main.cpp +++ b/example/hybrid/foolib/build.main.cpp @@ -11,15 +11,15 @@ constexpr std::string_view EXE = "build"; int main(int argc, char **argv) { // 1. Get arguments - Args args; + Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - args.Parse(argc, argv); + Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); + Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); + Args::Parse(argc, argv); // 2. Initialize your environment - Register reg(args); + Register reg; // 3. Pre-build steps reg.Clean(clean_cb); diff --git a/example/hybrid/generic/CMakeLists.txt b/example/hybrid/generic/CMakeLists.txt index 6d0520a0..8695177f 100644 --- a/example/hybrid/generic/CMakeLists.txt +++ b/example/hybrid/generic/CMakeLists.txt @@ -23,8 +23,6 @@ endif() # Run your build file add_custom_target(run_hybrid_generic_example - COMMAND hybrid_generic_example --help-all - COMMAND hybrid_generic_example toolchain --help-all COMMAND hybrid_generic_example --config ${CMAKE_CURRENT_SOURCE_DIR}/build_generic.toml # COMMAND dot -Tpng graph.dot -o graph.PNG WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/example/hybrid/generic/build.cpp b/example/hybrid/generic/build.cpp index 605ed4a0..aeba69ac 100644 --- a/example/hybrid/generic/build.cpp +++ b/example/hybrid/generic/build.cpp @@ -23,7 +23,7 @@ int main(int argc, char **argv) { // 1. Get arguments ArgToolchain custom_toolchain; TargetType default_lib_type{TargetType::StaticLibrary}; - Args args; + Args::Init(); try { const std::map lib_type_map_{ @@ -31,21 +31,21 @@ int main(int argc, char **argv) { {"DynamicLib", TargetType::DynamicLibrary}, }; - args.Ref() + Args::Ref() .add_option("--default_lib_type", default_lib_type, "Default Lib Type") ->transform(CLI::CheckedTransformer(lib_type_map_, CLI::ignore_case)) ->group("Custom"); // NOTE, You can add more custom toolchains as per your requirement - args.AddToolchain("user", "User defined toolchain", custom_toolchain); + Args::AddToolchain("user", "User defined toolchain", custom_toolchain); } catch (const std::exception &e) { std::cout << "EXCEPTION " << e.what() << std::endl; } - args.Parse(argc, argv); + Args::Parse(argc, argv); // 2. Initialize your environment - Register reg(args); + Register reg; // 3. Pre-build steps reg.Clean(clean_cb); diff --git a/example/hybrid/pch/build.cpp b/example/hybrid/pch/build.cpp index 8f7bc63d..7badb4b6 100644 --- a/example/hybrid/pch/build.cpp +++ b/example/hybrid/pch/build.cpp @@ -13,15 +13,15 @@ static void cflags_build_cb(BaseTarget &cflags); int main(int argc, char **argv) { // 1. Get arguments - Args args; + Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - args.Parse(argc, argv); + Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); + Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); + Args::Parse(argc, argv); // 2. Initialize your environment - Register reg(args); + Register reg; // 3. Pre-build steps reg.Clean(clean_cb); diff --git a/example/hybrid/simple/build.cpp b/example/hybrid/simple/build.cpp index ec4d5d80..4f7458e9 100644 --- a/example/hybrid/simple/build.cpp +++ b/example/hybrid/simple/build.cpp @@ -13,15 +13,15 @@ static void cflags_build_cb(BaseTarget &cflags); int main(int argc, char **argv) { // 1. Get arguments - Args args; + Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - args.Parse(argc, argv); + Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); + Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); + Args::Parse(argc, argv); // 2. Initialize your environment - Register reg(args); + Register reg; // 3. Pre-build steps reg.Clean(clean_cb); diff --git a/example/hybrid/single/build.cpp b/example/hybrid/single/build.cpp index 6ab78d85..ec21de0a 100644 --- a/example/hybrid/single/build.cpp +++ b/example/hybrid/single/build.cpp @@ -10,13 +10,13 @@ static void hello_world_build_cb(BaseTarget &target); int main(int argc, char **argv) { // 1. Get arguments - Args args; + Args::Init(); ArgToolchain arg_gcc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.Parse(argc, argv); + Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); + Args::Parse(argc, argv); // 2. Initialize your environment - Register reg(args); + Register reg; // 3. Pre-build steps reg.Clean(clean_cb); diff --git a/example/hybrid/target_info/build.cpp b/example/hybrid/target_info/build.cpp index f4926d01..b679a2df 100644 --- a/example/hybrid/target_info/build.cpp +++ b/example/hybrid/target_info/build.cpp @@ -14,15 +14,15 @@ static void genericadd2_build_cb(BaseTarget &genericadd, int main(int argc, char **argv) { // 1. Get arguments - Args args; + Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - args.Parse(argc, argv); + Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); + Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); + Args::Parse(argc, argv); // 2. Initialize your environment - Register reg(args); + Register reg; // 3. Pre-build steps reg.Clean(clean_cb); From b9df847d9c936e3b82b835d79091f134f07257d6 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 28 Mar 2022 21:20:17 -0700 Subject: [PATCH 11/35] `Args::Instance` constructed from `Args` for better segregation (#203) --- bootstrap/main.buildcc.cpp | 7 +- buildcc/lib/args/include/args/args.h | 104 ++++++++------- buildcc/lib/args/include/args/register.h | 3 - buildcc/lib/args/mock/parse.cpp | 2 +- buildcc/lib/args/src/args.cpp | 132 +++++++++++--------- buildcc/lib/args/src/parse.cpp | 7 +- buildcc/lib/args/test/test_args.cpp | 118 ++++++++++++----- buildcc/lib/args/test/test_register.cpp | 65 +++++----- buildexe/buildexe.cpp | 3 +- buildexe/include/buildexe/args_setup.h | 39 +++--- buildexe/src/args_setup.cpp | 88 ++++++------- docs/source/user_api/args.rst | 3 +- example/buildexe/libs/build.main.cpp | 1 - example/hybrid/custom_target/build.main.cpp | 12 +- example/hybrid/dep_chaining/build.cpp | 8 +- example/hybrid/external_lib/build.main.cpp | 8 +- example/hybrid/foolib/build.main.cpp | 8 +- example/hybrid/generic/build.cpp | 37 +++--- example/hybrid/pch/build.cpp | 8 +- example/hybrid/simple/build.cpp | 8 +- example/hybrid/single/build.cpp | 6 +- example/hybrid/target_info/build.cpp | 8 +- 22 files changed, 374 insertions(+), 301 deletions(-) diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index 4882d013..7ee8afd6 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -33,13 +33,12 @@ static void hybrid_simple_example_cb(BaseTarget &target, const BaseTarget &libbuildcc); int main(int argc, char **argv) { - Args::Init(); ArgToolchain custom_toolchain_arg; - Args::AddToolchain("host", "Host Toolchain", custom_toolchain_arg); - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("host", "Host Toolchain", custom_toolchain_arg) + .Parse(argc, argv); Register reg; - ; reg.Clean(clean_cb); BaseToolchain toolchain = custom_toolchain_arg.ConstructToolchain(); diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index a8b43d51..f26e006d 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -85,57 +85,71 @@ struct ArgTarget { std::string link_command{""}; }; +struct ArgCustom { + virtual void Add(CLI::App &app) = 0; +}; + class Args { -public: +private: + class Instance { + public: + /** + * @brief Parse command line information to CLI11 + * + * @param argc from int main(int argc, char ** argv) + * @param argv from int main(int argc, char ** argv) + */ + static void Parse(int argc, const char *const *argv); + + /** + * @brief Add toolchain with a unique name and description + * + * @param out Receive the toolchain information through the CLI + * @param initial Set the default toolchain information as a fallback + */ + Instance &AddToolchain(const std::string &name, + const std::string &description, ArgToolchain &out, + const ArgToolchain &initial = ArgToolchain()); + + /** + * @brief Add toolchain with a unique name and description + * + * @param out Receive the toolchain information through the CLI + * @param initial Set the default toolchain information as a fallback + */ + Instance &AddTarget(const std::string &name, const std::string &description, + ArgTarget &out, const ArgTarget &initial = ArgTarget()); + + /** + * @brief Custom callback for data + * + * @param add_cb Add callback that exposes underlying CLI::App + */ + Instance &AddCustomCallback(const std::function &add_cb); + + /** + * @brief Add custom data + * + * @param data Derive from `buildcc::ArgCustom` and override the `Add` API + */ + Instance &AddCustomData(ArgCustom &data); + }; + + struct Internal { + Instance instance; + CLI::App app{"BuildCC Buildsystem"}; + CLI::App *toolchain{nullptr}; + CLI::App *target{nullptr}; + }; + public: Args() = delete; Args(const Args &) = delete; Args(Args &&) = delete; - static void Init(); + static Instance &Init(); static void Deinit(); - /** - * @brief Parse command line information to CLI11 - * - * @param argc from int main(int argc, char ** argv) - * @param argv from int main(int argc, char ** argv) - */ - static void Parse(int argc, const char *const *argv); - - /** - * @brief Modifiable reference to CLI::App (CLI11) - */ - static CLI::App &Ref(); - - /** - * @brief Constant reference to CLI::App (CLI11) - */ - static const CLI::App &ConstRef(); - - // Setters - - /** - * @brief Add toolchain with a unique name and description - * - * @param out Receive the toolchain information through the CLI - * @param initial Set the default toolchain information as a fallback - */ - static void AddToolchain(const std::string &name, - const std::string &description, ArgToolchain &out, - const ArgToolchain &initial = ArgToolchain()); - - /** - * @brief Add Target config commands with a unique name and description - * - * @param out Receive the target command information through the CLI - * @param initial Set the default target command information as a fallback - * - * TODO, Update with other options for TargetConfig - */ - static void AddTarget(const std::string &name, const std::string &description, - ArgTarget &out, const ArgTarget &initial = ArgTarget()); - // Getters static bool Clean(); static env::LogLevel GetLogLevel(); @@ -145,6 +159,10 @@ class Args { private: static void RootArgs(); + static CLI::App &Ref(); + +private: + static std::unique_ptr internal_; }; } // namespace buildcc diff --git a/buildcc/lib/args/include/args/register.h b/buildcc/lib/args/include/args/register.h index c15a0b83..110e5246 100644 --- a/buildcc/lib/args/include/args/register.h +++ b/buildcc/lib/args/include/args/register.h @@ -33,7 +33,6 @@ namespace buildcc { class Register { public: - // Register(const Args &args) : args_(args) { Initialize(); } Register() { Initialize(); } Register(const Register &) = delete; @@ -155,8 +154,6 @@ class Register { void BuildStoreTask(const std::string &unique_id, const tf::Task &task); private: - // const Args &args_; - // Build tf::Taskflow build_tf_{"Targets"}; diff --git a/buildcc/lib/args/mock/parse.cpp b/buildcc/lib/args/mock/parse.cpp index dcbccc3c..53213201 100644 --- a/buildcc/lib/args/mock/parse.cpp +++ b/buildcc/lib/args/mock/parse.cpp @@ -4,7 +4,7 @@ namespace buildcc { -void Args::Parse(int argc, const char *const *argv) { +void Args::Instance::Parse(int argc, const char *const *argv) { try { Ref().parse(argc, argv); } catch (const CLI::ParseError &e) { diff --git a/buildcc/lib/args/src/args.cpp b/buildcc/lib/args/src/args.cpp index ec6b4a33..378bd7d4 100644 --- a/buildcc/lib/args/src/args.cpp +++ b/buildcc/lib/args/src/args.cpp @@ -90,38 +90,24 @@ buildcc::env::LogLevel loglevel_{buildcc::env::LogLevel::Info}; fs::path project_root_dir_{""}; fs::path project_build_dir_{"_internal"}; -// Internal -// std::unique_ptr app_; -// CLI::App *toolchain_{nullptr}; -// CLI::App *target_{nullptr}; - -struct ArgsInstance { - CLI::App app_{"BuildCC Buildsystem"}; - CLI::App *toolchain_{nullptr}; - CLI::App *target_{nullptr}; -}; - -std::unique_ptr args_instance_; - } // namespace namespace buildcc { -void Args::Init() { - if (!args_instance_) { - args_instance_ = std::make_unique(); - args_instance_->toolchain_ = +std::unique_ptr Args::internal_; + +Args::Instance &Args::Init() { + if (!internal_) { + internal_ = std::make_unique(); + internal_->toolchain = Ref().add_subcommand(kToolchainSubcommand, kToolchainDesc); - args_instance_->target_ = - Ref().add_subcommand(kTargetSubcommand, kTargetDesc); + internal_->target = Ref().add_subcommand(kTargetSubcommand, kTargetDesc); RootArgs(); } + return internal_->instance; } -void Args::Deinit() { args_instance_.reset(nullptr); } - -CLI::App &Args::Ref() { return args_instance_->app_; } -const CLI::App &Args::ConstRef() { return args_instance_->app_; } +void Args::Deinit() { internal_.reset(nullptr); } bool Args::Clean() { return clean_; } env::LogLevel Args::GetLogLevel() { return loglevel_; } @@ -129,13 +115,47 @@ env::LogLevel Args::GetLogLevel() { return loglevel_; } const fs::path &Args::GetProjectRootDir() { return project_root_dir_; } const fs::path &Args::GetProjectBuildDir() { return project_build_dir_; } -void Args::AddToolchain(const std::string &name, const std::string &description, - ArgToolchain &out, const ArgToolchain &initial) { - CLI::App *toolchain_ = args_instance_->toolchain_; - env::assert_fatal(toolchain_ != nullptr, +// Private + +void Args::RootArgs() { + auto &app = Ref(); + app.set_help_all_flag(kHelpAllParam, kHelpAllDesc); + + app.set_config(kConfigParam, "", kConfigDesc)->expected(kMinFiles, kMaxFiles); + + // Root flags + auto *root_group = app.add_option_group(kRootGroup); + + root_group->add_flag(kCleanParam, clean_, kCleanDesc); + root_group->add_option(kLoglevelParam, loglevel_, kLoglevelDesc) + ->transform(CLI::CheckedTransformer(kLogLevelMap, CLI::ignore_case)); + + // Dir flags + root_group->add_option(kRootDirParam, project_root_dir_, kRootDirDesc) + ->required(); + root_group->add_option(kBuildDirParam, project_build_dir_, kBuildDirDesc) + ->required(); +} + +CLI::App &Args::Ref() { return internal_->app; } + +// Args::Instance + +/** + * @brief Add toolchain with a unique name and description + * + * @param out Receive the toolchain information through the CLI + * @param initial Set the default toolchain information as a fallback + */ +Args::Instance &Args::Instance::AddToolchain(const std::string &name, + const std::string &description, + ArgToolchain &out, + const ArgToolchain &initial) { + CLI::App *toolchain = internal_->toolchain; + env::assert_fatal(toolchain != nullptr, "Initialize Args using the Args::Init API"); CLI::App *t_user = - toolchain_->add_subcommand(name, description)->group(kToolchainGroup); + toolchain->add_subcommand(name, description)->group(kToolchainGroup); t_user->add_flag(kToolchainBuildParam, out.state.build); t_user->add_flag(kToolchainTestParam, out.state.test); @@ -153,42 +173,42 @@ void Args::AddToolchain(const std::string &name, const std::string &description, ->default_val(initial.executables.archiver); t_user->add_option(kToolchainLinkerParam, out.executables.linker) ->default_val(initial.executables.linker); + return *this; } -void Args::AddTarget(const std::string &name, const std::string &description, - ArgTarget &out, const ArgTarget &initial) { - CLI::App *target_ = args_instance_->target_; - env::assert_fatal(target_ != nullptr, +/** + * @brief Add toolchain with a unique name and description + * + * @param out Receive the toolchain information through the CLI + * @param initial Set the default toolchain information as a fallback + */ +Args::Instance &Args::Instance::AddTarget(const std::string &name, + const std::string &description, + ArgTarget &out, + const ArgTarget &initial) { + CLI::App *target = internal_->target; + env::assert_fatal(target != nullptr, "Initialize Args using the Args::Init API"); - CLI::App *target_user = - target_->add_subcommand(name, description)->group(kTargetGroup); - target_user->add_option(kTargetCompileCommandParam, out.compile_command) + CLI::App *targetuser = + target->add_subcommand(name, description)->group(kTargetGroup); + targetuser->add_option(kTargetCompileCommandParam, out.compile_command) ->default_val(initial.compile_command); - target_user->add_option(kTargetLinkCommandParam, out.link_command) + targetuser->add_option(kTargetLinkCommandParam, out.link_command) ->default_val(initial.link_command); + return *this; } -// Private - -void Args::RootArgs() { - Ref().set_help_all_flag(kHelpAllParam, kHelpAllDesc); - - Ref() - .set_config(kConfigParam, "", kConfigDesc) - ->expected(kMinFiles, kMaxFiles); - - // Root flags - auto *root_group = Ref().add_option_group(kRootGroup); - - root_group->add_flag(kCleanParam, clean_, kCleanDesc); - root_group->add_option(kLoglevelParam, loglevel_, kLoglevelDesc) - ->transform(CLI::CheckedTransformer(kLogLevelMap, CLI::ignore_case)); +Args::Instance &Args::Instance::AddCustomCallback( + const std::function &add_cb) { + auto &app = Ref(); + add_cb(app); + return *this; +} - // Dir flags - root_group->add_option(kRootDirParam, project_root_dir_, kRootDirDesc) - ->required(); - root_group->add_option(kBuildDirParam, project_build_dir_, kBuildDirDesc) - ->required(); +Args::Instance &Args::Instance::AddCustomData(ArgCustom &data) { + auto &app = Ref(); + data.Add(app); + return *this; } } // namespace buildcc diff --git a/buildcc/lib/args/src/parse.cpp b/buildcc/lib/args/src/parse.cpp index 08baac2f..bbb6b745 100644 --- a/buildcc/lib/args/src/parse.cpp +++ b/buildcc/lib/args/src/parse.cpp @@ -18,11 +18,12 @@ namespace buildcc { -void Args::Parse(int argc, const char *const *argv) { +void Args::Instance::Parse(int argc, const char *const *argv) { + auto &app = Ref(); try { - Ref().parse(argc, argv); + app.parse(argc, argv); } catch (const CLI::ParseError &e) { - exit(ConstRef().exit(e)); + exit(app.exit(e)); } } diff --git a/buildcc/lib/args/test/test_args.cpp b/buildcc/lib/args/test/test_args.cpp index 8c4c3979..697df743 100644 --- a/buildcc/lib/args/test/test_args.cpp +++ b/buildcc/lib/args/test/test_args.cpp @@ -16,20 +16,18 @@ TEST_GROUP(ArgsTestGroup) // clang-format on TEST(ArgsTestGroup, Args_BasicParse) { - UT_PRINT("Args_BasicParse\r\n"); std::vector av{"", "--config", "configs/basic_parse.toml"}; int argc = av.size(); - buildcc::Args::Init(); - buildcc::Args::Init(); // Second init does nothing when already initialized - buildcc::Args::Parse(argc, av.data()); + (void)buildcc::Args::Init(); + auto &instance = buildcc::Args::Init(); // Second init does nothing when + // already initialized + instance.Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); CHECK_TRUE(buildcc::Args::Clean()); - buildcc::Args::Ref().name("new_name"); - STRCMP_EQUAL(buildcc::Args::Ref().get_name().c_str(), "new_name"); } TEST(ArgsTestGroup, Args_BasicExit) { @@ -38,8 +36,8 @@ TEST(ArgsTestGroup, Args_BasicExit) { "--help"}; int argc = av.size(); - buildcc::Args::Init(); - CHECK_THROWS(std::exception, buildcc::Args::Parse(argc, av.data())); + auto &instance = buildcc::Args::Init(); + CHECK_THROWS(std::exception, instance.Parse(argc, av.data())); } TEST(ArgsTestGroup, Args_MultiToml) { @@ -47,8 +45,7 @@ TEST(ArgsTestGroup, Args_MultiToml) { "--config", "configs/no_clean.toml"}; int argc = av.size(); - buildcc::Args::Init(); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init().Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -61,10 +58,10 @@ TEST(ArgsTestGroup, Args_CustomToolchain) { "--config", "configs/gcc_toolchain.toml"}; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -95,12 +92,12 @@ TEST(ArgsTestGroup, Args_MultipleCustomToolchain) { }; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -133,18 +130,18 @@ TEST(ArgsTestGroup, Args_MultipleCustomToolchain) { } TEST(ArgsTestGroup, Args_DuplicateCustomToolchain) { - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain other_gcc_toolchain; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); + auto &instance = buildcc::Args::Init().AddToolchain( + "gcc", "Generic gcc toolchain", gcc_toolchain); // CLI11 Throws an exception when multiple toolchains with same name are added // NOTE, This behaviour does not need to be tested since it is provided by // CLI11 // This test is as an example of wrong usage by the user CHECK_THROWS(std::exception, - (buildcc::Args::AddToolchain("gcc", "Other gcc toolchain ", - other_gcc_toolchain))); + (instance.AddToolchain("gcc", "Other gcc toolchain ", + other_gcc_toolchain))); } TEST(ArgsTestGroup, Args_CustomTarget) { @@ -159,12 +156,12 @@ TEST(ArgsTestGroup, Args_CustomTarget) { }; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgTarget gcc_target; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::AddTarget("gcc", "Generic gcc target", gcc_target); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddTarget("gcc", "Generic gcc target", gcc_target) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -207,16 +204,17 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { }; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgTarget gcc_target; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::AddTarget("gcc", "Generic gcc target", gcc_target); buildcc::ArgToolchain msvc_toolchain; buildcc::ArgTarget msvc_target; - buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - buildcc::Args::AddTarget("msvc", "Generic msvc target", msvc_target); - buildcc::Args::Parse(argc, av.data()); + + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddTarget("gcc", "Generic gcc target", gcc_target) + .AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain) + .AddTarget("msvc", "Generic msvc target", msvc_target) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -266,6 +264,64 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { "{compiled_sources}"); } +TEST(ArgsTestGroup, Args_CustomCallback) { + std::vector av{"", + "--config", + "configs/basic_parse.toml", + "--random_bool", + "true", + "--random_string", + "hello world"}; + int argc = av.size(); + + bool random_bool{false}; + std::string random_string; + auto &instance = buildcc::Args::Init(); + instance.AddCustomCallback([&](CLI::App &app) { + app.add_option("--random_bool", random_bool, "Random bool"); + app.add_option("--random_string", random_string, "Random string"); + }); + instance.Parse(argc, av.data()); + + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); + CHECK_TRUE(random_bool); + STRCMP_EQUAL(random_string.c_str(), "hello world"); +} + +TEST(ArgsTestGroup, Args_CustomData) { + struct RandomGroupedData : public buildcc::ArgCustom { + void Add(CLI::App &app) override { + app.add_option("--random_bool", random_bool, "Random bool"); + app.add_option("--random_string", random_string, "Random string"); + } + + bool random_bool{false}; + std::string random_string; + }; + + std::vector av{"", + "--config", + "configs/basic_parse.toml", + "--random_bool", + "true", + "--random_string", + "hello world"}; + int argc = av.size(); + + RandomGroupedData grouped_data; + buildcc::Args::Init().AddCustomData(grouped_data).Parse(argc, av.data()); + + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); + CHECK_TRUE(grouped_data.random_bool); + STRCMP_EQUAL(grouped_data.random_string.c_str(), "hello world"); +} + int main(int ac, char **av) { MemoryLeakWarningPlugin::destroyGlobalDetector(); return CommandLineTestRunner::RunAllTests(ac, av); diff --git a/buildcc/lib/args/test/test_register.cpp b/buildcc/lib/args/test/test_register.cpp index 81dbd9cf..bcd6b191 100644 --- a/buildcc/lib/args/test/test_register.cpp +++ b/buildcc/lib/args/test/test_register.cpp @@ -25,8 +25,7 @@ TEST(RegisterTestGroup, Register_Initialize) { std::vector av{"", "--config", "configs/basic_parse.toml"}; int argc = av.size(); - buildcc::Args::Init(); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init().Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -41,8 +40,7 @@ TEST(RegisterTestGroup, Register_Clean) { std::vector av{"", "--config", "configs/basic_parse.toml"}; int argc = av.size(); - buildcc::Args::Init(); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init().Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -65,8 +63,7 @@ TEST(RegisterTestGroup, Register_Clean) { }; int argc = av.size(); - buildcc::Args::Init(); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init().Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -89,12 +86,12 @@ TEST(RegisterTestGroup, Register_Build) { }; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -137,12 +134,12 @@ TEST(RegisterTestGroup, Register_NoBuildAndDep) { }; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -221,12 +218,12 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { }; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -316,12 +313,12 @@ TEST(RegisterTestGroup, Register_DepDuplicate) { }; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -392,12 +389,12 @@ TEST(RegisterTestGroup, Register_DepCyclic) { }; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -468,12 +465,12 @@ TEST(RegisterTestGroup, Register_Test) { }; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); @@ -553,12 +550,12 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { }; int argc = av.size(); - buildcc::Args::Init(); buildcc::ArgToolchain gcc_toolchain; buildcc::ArgToolchain msvc_toolchain; - buildcc::Args::AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain); - buildcc::Args::AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain); - buildcc::Args::Parse(argc, av.data()); + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain) + .Parse(argc, av.data()); STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); diff --git a/buildexe/buildexe.cpp b/buildexe/buildexe.cpp index 7077d8dd..0af85b3f 100644 --- a/buildexe/buildexe.cpp +++ b/buildexe/buildexe.cpp @@ -42,8 +42,7 @@ int main(int argc, char **argv) { // BuildExeArgs buildexe_args; - buildexe_args.Setup(); - buildexe_args.Parse(argc, argv); + buildexe_args.Setup(argc, argv); // TODO, Add Verification subcommand here for OS, Compiler etc! // os win, linux considerations diff --git a/buildexe/include/buildexe/args_setup.h b/buildexe/include/buildexe/args_setup.h index 26419a53..dde67f08 100644 --- a/buildexe/include/buildexe/args_setup.h +++ b/buildexe/include/buildexe/args_setup.h @@ -26,13 +26,17 @@ enum class BuildExeMode { Script, }; -struct ArgTargetInfo { +struct ArgTargetInfo : public ArgCustom { + void Add(CLI::App &app) override; + std::string name; TargetType type; fs::path relative_to_root; }; -struct ArgTargetInputs { +struct ArgTargetInputs : public ArgCustom { + void Add(CLI::App &app) override; + // Sources std::vector source_files; std::vector include_dirs; @@ -50,7 +54,9 @@ struct ArgTargetInputs { std::vector link_flags; }; -struct ArgScriptInfo { +struct ArgScriptInfo : public ArgCustom { + void Add(CLI::App &app) override; + std::vector configs; }; @@ -59,10 +65,16 @@ struct LibInfo { std::string absolute_lib_path; }; +struct ArgLibsInfo : public ArgCustom { + void Add(CLI::App &app) override; + + std::vector libs_info; + std::vector lib_build_files; +}; + class BuildExeArgs { public: - void Setup(); - void Parse(int argc, char **argv) { Args::Parse(argc, argv); } + void Setup(int argc, char **argv); // Getters const ArgToolchain &GetHostToolchainArg() const { @@ -73,28 +85,23 @@ class BuildExeArgs { const ArgScriptInfo &GetScriptInfo() const { return out_scriptinfo_; } BuildExeMode GetBuildMode() const { return out_mode_; } - const std::vector &GetLibsInfo() const { return libs_info_; } + const std::vector &GetLibsInfo() const { + return out_libsinfo_.libs_info; + } const std::vector &GetLibBuildFiles() const { - return lib_build_files_; + return out_libsinfo_.lib_build_files; } private: - void SetupBuildMode(); - void SetupTargetInfo(); - void SetupTargetInputs(); - void SetupScriptMode(); - void SetupLibs(); + void SetupBuildMode(CLI::App &app); private: ArgToolchain host_toolchain_arg_; ArgTargetInfo out_targetinfo_; ArgTargetInputs out_targetinputs_; ArgScriptInfo out_scriptinfo_; - + ArgLibsInfo out_libsinfo_; BuildExeMode out_mode_; - - std::vector libs_info_; - std::vector lib_build_files_; }; } // namespace buildcc diff --git a/buildexe/src/args_setup.cpp b/buildexe/src/args_setup.cpp index 3ec0fb4f..edee4ada 100644 --- a/buildexe/src/args_setup.cpp +++ b/buildexe/src/args_setup.cpp @@ -32,91 +32,73 @@ static const std::unordered_map kTargetTypeMap{ {"dynamicLibrary", TargetType::DynamicLibrary}, }; -void BuildExeArgs::Setup() { - Args::Init(); - Args::AddToolchain("host", "Host Toolchain", host_toolchain_arg_); - SetupBuildMode(); - SetupTargetInfo(); - SetupTargetInputs(); - SetupScriptMode(); - SetupLibs(); +void BuildExeArgs::Setup(int argc, char **argv) { + Args::Init() + .AddToolchain("host", "Host Toolchain", host_toolchain_arg_) + .AddCustomData(out_targetinfo_) + .AddCustomData(out_targetinputs_) + .AddCustomData(out_scriptinfo_) + .AddCustomData(out_libsinfo_) + .AddCustomCallback([&](CLI::App &app) { SetupBuildMode(app); }) + .Parse(argc, argv); } -void BuildExeArgs::SetupBuildMode() { - Args::Ref() - .add_option("--mode", out_mode_, "Provide BuildExe run mode") +void BuildExeArgs::SetupBuildMode(CLI::App &app) { + app.add_option("--mode", out_mode_, "Provide BuildExe run mode") ->transform(CLI::CheckedTransformer(kBuildExeModeMap, CLI::ignore_case)) ->required(); } -// TODO, Add subcommand [build.info] -void BuildExeArgs::SetupTargetInfo() { +void ArgTargetInfo::Add(CLI::App &app) { constexpr const char *const kProjectInfo = "Project Info"; - auto &app = Args::Ref(); - auto *project_info_app = app.add_option_group(kProjectInfo); - project_info_app - ->add_option("--name", out_targetinfo_.name, "Provide Target name") + project_info_app->add_option("--name", name, "Provide Target name") ->required(); - project_info_app - ->add_option("--type", out_targetinfo_.type, "Provide Target Type") + project_info_app->add_option("--type", type, "Provide Target Type") ->transform(CLI::CheckedTransformer(kTargetTypeMap, CLI::ignore_case)) ->required(); project_info_app - ->add_option("--relative_to_root", out_targetinfo_.relative_to_root, + ->add_option("--relative_to_root", relative_to_root, "Provide Target relative to root") ->required(); } -// TODO, Add subcommand [build.inputs] -// TODO, Add group, group by sources, headers, inncludes on CLI -void BuildExeArgs::SetupTargetInputs() { +void ArgTargetInputs::Add(CLI::App &app) { constexpr const char *const kTargetInputs = "Target Inputs"; - auto &app = Args::Ref(); - auto *target_inputs_app = app.add_option_group(kTargetInputs); - target_inputs_app->add_option("--srcs", out_targetinputs_.source_files, - "Provide source files"); - target_inputs_app->add_option("--includes", out_targetinputs_.include_dirs, + target_inputs_app->add_option("--srcs", source_files, "Provide source files"); + target_inputs_app->add_option("--includes", include_dirs, "Provide include dirs"); - target_inputs_app->add_option("--lib_dirs", out_targetinputs_.lib_dirs, - "Provide lib dirs"); - target_inputs_app->add_option("--external_libs", - out_targetinputs_.external_lib_deps, + target_inputs_app->add_option("--lib_dirs", lib_dirs, "Provide lib dirs"); + target_inputs_app->add_option("--external_libs", external_lib_deps, "Provide external libs"); - target_inputs_app->add_option("--preprocessor_flags", - out_targetinputs_.preprocessor_flags, + target_inputs_app->add_option("--preprocessor_flags", preprocessor_flags, "Provide Preprocessor flags"); - target_inputs_app->add_option("--common_compile_flags", - out_targetinputs_.common_compile_flags, + target_inputs_app->add_option("--common_compile_flags", common_compile_flags, "Provide CommonCompile Flags"); - target_inputs_app->add_option("--asm_compile_flags", - out_targetinputs_.asm_compile_flags, + target_inputs_app->add_option("--asm_compile_flags", asm_compile_flags, "Provide AsmCompile Flags"); - target_inputs_app->add_option("--c_compile_flags", - out_targetinputs_.c_compile_flags, + target_inputs_app->add_option("--c_compile_flags", c_compile_flags, "Provide CCompile Flags"); - target_inputs_app->add_option("--cpp_compile_flags", - out_targetinputs_.cpp_compile_flags, + target_inputs_app->add_option("--cpp_compile_flags", cpp_compile_flags, "Provide CppCompile Flags"); - target_inputs_app->add_option("--link_flags", out_targetinputs_.link_flags, + target_inputs_app->add_option("--link_flags", link_flags, "Provide Link Flags"); -} +}; -void BuildExeArgs::SetupScriptMode() { - auto *script_args = Args::Ref().add_subcommand("script"); - script_args->add_option("--configs", out_scriptinfo_.configs, - "Config files for script mode"); +void ArgScriptInfo::Add(CLI::App &app) { + auto *script_args = app.add_subcommand("script"); + script_args->add_option("--configs", configs, "Config files for script mode"); } -void BuildExeArgs::SetupLibs() { - auto *libs_app = Args::Ref().add_subcommand("libs", "Libraries"); +void ArgLibsInfo::Add(CLI::App &app) { + auto *libs_app = app.add_subcommand("libs", "Libraries"); std::error_code ec; fs::directory_iterator dir_iter = fs::directory_iterator(BuildccHome::GetBuildccLibsDir(), ec); @@ -133,13 +115,13 @@ void BuildExeArgs::SetupLibs() { LibInfo lib_info; lib_info.lib_name = lib_name; lib_info.absolute_lib_path = fmt::format("{}", lib_path); - libs_info_.push_back(lib_info); + libs_info.push_back(lib_info); auto add_lib_files_cb_func = [lib_path, this](const std::vector &paths) { for (const auto &p : paths) { - fs::path absolute_file_path = lib_path / p; - lib_build_files_.push_back(absolute_file_path); + fs::path absolute_file_path = (lib_path / p).make_preferred(); + lib_build_files.push_back(absolute_file_path); } }; diff --git a/docs/source/user_api/args.rst b/docs/source/user_api/args.rst index 383268c7..a0c8d482 100644 --- a/docs/source/user_api/args.rst +++ b/docs/source/user_api/args.rst @@ -5,7 +5,8 @@ args.h ------- .. doxygenclass:: buildcc::Args - :members: Args, Parse, Ref, ConstRef, AddToolchain, Clean, GetLogLevel, GetProjectRootDir, GetProjectBuildDir + +.. doxygenclass:: buildcc::Args::Instance .. doxygenstruct:: buildcc::ArgToolchainState diff --git a/example/buildexe/libs/build.main.cpp b/example/buildexe/libs/build.main.cpp index 5937c5ee..c051e83b 100644 --- a/example/buildexe/libs/build.main.cpp +++ b/example/buildexe/libs/build.main.cpp @@ -24,7 +24,6 @@ int main(int argc, char **argv) { // 2. Initialize your environment Register reg; - ; // 3. Pre-build steps reg.Clean(clean_cb); diff --git a/example/hybrid/custom_target/build.main.cpp b/example/hybrid/custom_target/build.main.cpp index 50390bd3..6b0829c0 100644 --- a/example/hybrid/custom_target/build.main.cpp +++ b/example/hybrid/custom_target/build.main.cpp @@ -9,16 +9,16 @@ static constexpr std::string_view EXE = "build"; int main(int argc, char **argv) { // 1. Get arguments - Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; ArgToolchain toolchain_clang_gnu; ArgTarget target_clang_gnu; - Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - Args::AddToolchain("clang_gnu", "Clang GNU toolchain", toolchain_clang_gnu); - Args::AddTarget("clang_gnu", "Clang GNU target", target_clang_gnu); - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) + .AddToolchain("clang_gnu", "Clang GNU toolchain", toolchain_clang_gnu) + .AddTarget("clang_gnu", "Clang GNU target", target_clang_gnu) + .Parse(argc, argv); // 2. Initialize your environment Register reg; diff --git a/example/hybrid/dep_chaining/build.cpp b/example/hybrid/dep_chaining/build.cpp index 915507bd..49722ad4 100644 --- a/example/hybrid/dep_chaining/build.cpp +++ b/example/hybrid/dep_chaining/build.cpp @@ -16,12 +16,12 @@ static void c_generator_cb(BaseGenerator &generator); int main(int argc, char **argv) { // 1. Get arguments - Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) + .Parse(argc, argv); // 2. Initialize your environment Register reg; diff --git a/example/hybrid/external_lib/build.main.cpp b/example/hybrid/external_lib/build.main.cpp index fd56b11f..b181281b 100644 --- a/example/hybrid/external_lib/build.main.cpp +++ b/example/hybrid/external_lib/build.main.cpp @@ -11,12 +11,12 @@ constexpr const char *const EXE = "build"; int main(int argc, char **argv) { // 1. Get arguments - Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) + .Parse(argc, argv); // 2. Initialize your environment Register reg; diff --git a/example/hybrid/foolib/build.main.cpp b/example/hybrid/foolib/build.main.cpp index bbd3eba6..dc723d7b 100644 --- a/example/hybrid/foolib/build.main.cpp +++ b/example/hybrid/foolib/build.main.cpp @@ -11,12 +11,12 @@ constexpr std::string_view EXE = "build"; int main(int argc, char **argv) { // 1. Get arguments - Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) + .Parse(argc, argv); // 2. Initialize your environment Register reg; diff --git a/example/hybrid/generic/build.cpp b/example/hybrid/generic/build.cpp index aeba69ac..3b9dcaa3 100644 --- a/example/hybrid/generic/build.cpp +++ b/example/hybrid/generic/build.cpp @@ -15,6 +15,7 @@ constexpr std::string_view EXE = "build"; // Function Prototypes static void clean_cb(); +static void args_lib_type_cb(CLI::App &app, TargetType &lib_type); static void foolib_build_cb(BaseTarget &foolib_target); static void generic_build_cb(BaseTarget &generic_target, BaseTarget &foolib_target); @@ -23,26 +24,11 @@ int main(int argc, char **argv) { // 1. Get arguments ArgToolchain custom_toolchain; TargetType default_lib_type{TargetType::StaticLibrary}; - Args::Init(); - - try { - const std::map lib_type_map_{ - {"StaticLib", TargetType::StaticLibrary}, - {"DynamicLib", TargetType::DynamicLibrary}, - }; - - Args::Ref() - .add_option("--default_lib_type", default_lib_type, "Default Lib Type") - ->transform(CLI::CheckedTransformer(lib_type_map_, CLI::ignore_case)) - ->group("Custom"); - - // NOTE, You can add more custom toolchains as per your requirement - Args::AddToolchain("user", "User defined toolchain", custom_toolchain); - } catch (const std::exception &e) { - std::cout << "EXCEPTION " << e.what() << std::endl; - } - - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("user", "User defined toolchain", custom_toolchain) + .AddCustomCallback( + [&](CLI::App &app) { args_lib_type_cb(app, default_lib_type); }) + .Parse(argc, argv); // 2. Initialize your environment Register reg; @@ -119,6 +105,17 @@ static void clean_cb() { fs::remove_all(Project::GetBuildDir()); } +void args_lib_type_cb(CLI::App &app, TargetType &lib_type) { + const std::map lib_type_map_{ + {"StaticLib", TargetType::StaticLibrary}, + {"DynamicLib", TargetType::DynamicLibrary}, + }; + + app.add_option("--default_lib_type", lib_type, "Default Lib Type") + ->transform(CLI::CheckedTransformer(lib_type_map_, CLI::ignore_case)) + ->group("Custom"); +} + static void foolib_build_cb(BaseTarget &foolib_target) { fooTarget(foolib_target, Project::GetRootDir() / ".." / "foolib"); foolib_target.Build(); diff --git a/example/hybrid/pch/build.cpp b/example/hybrid/pch/build.cpp index 7badb4b6..a305367d 100644 --- a/example/hybrid/pch/build.cpp +++ b/example/hybrid/pch/build.cpp @@ -13,12 +13,12 @@ static void cflags_build_cb(BaseTarget &cflags); int main(int argc, char **argv) { // 1. Get arguments - Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) + .Parse(argc, argv); // 2. Initialize your environment Register reg; diff --git a/example/hybrid/simple/build.cpp b/example/hybrid/simple/build.cpp index 4f7458e9..94c447f7 100644 --- a/example/hybrid/simple/build.cpp +++ b/example/hybrid/simple/build.cpp @@ -13,12 +13,12 @@ static void cflags_build_cb(BaseTarget &cflags); int main(int argc, char **argv) { // 1. Get arguments - Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) + .Parse(argc, argv); // 2. Initialize your environment Register reg; diff --git a/example/hybrid/single/build.cpp b/example/hybrid/single/build.cpp index ec21de0a..491c8fc2 100644 --- a/example/hybrid/single/build.cpp +++ b/example/hybrid/single/build.cpp @@ -10,10 +10,10 @@ static void hello_world_build_cb(BaseTarget &target); int main(int argc, char **argv) { // 1. Get arguments - Args::Init(); ArgToolchain arg_gcc; - Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .Parse(argc, argv); // 2. Initialize your environment Register reg; diff --git a/example/hybrid/target_info/build.cpp b/example/hybrid/target_info/build.cpp index b679a2df..600a8c71 100644 --- a/example/hybrid/target_info/build.cpp +++ b/example/hybrid/target_info/build.cpp @@ -14,12 +14,12 @@ static void genericadd2_build_cb(BaseTarget &genericadd, int main(int argc, char **argv) { // 1. Get arguments - Args::Init(); ArgToolchain arg_gcc; ArgToolchain arg_msvc; - Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - Args::AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) + .Parse(argc, argv); // 2. Initialize your environment Register reg; From f51e2323523555eaadfe6af72bbe4fb0cc18a913 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 7 Apr 2022 23:23:15 -0700 Subject: [PATCH 12/35] Refactor `Register` constructable class to `Reg` static class (#204) --- bootstrap/include/bootstrap/build_buildcc.h | 6 +- bootstrap/include/bootstrap/build_tpl.h | 8 +- bootstrap/main.buildcc.cpp | 19 +- bootstrap/src/build_buildcc.cpp | 41 +- bootstrap/src/build_tpl.cpp | 15 +- buildcc/lib/args/include/args/args.h | 124 ++--- buildcc/lib/args/include/args/register.h | 152 ++++-- .../args/include/args/register/test_info.h | 4 +- buildcc/lib/args/mock/parse.cpp | 2 +- buildcc/lib/args/mock/tasks.cpp | 8 +- buildcc/lib/args/src/args.cpp | 36 +- buildcc/lib/args/src/parse.cpp | 2 +- buildcc/lib/args/src/register.cpp | 110 +++-- buildcc/lib/args/src/tasks.cpp | 22 +- buildcc/lib/args/test/test_args.cpp | 5 + buildcc/lib/args/test/test_register.cpp | 436 ++++++++++-------- buildexe/buildexe.cpp | 6 +- buildexe/include/buildexe/build_env_setup.h | 5 +- buildexe/src/build_env_setup.cpp | 10 +- docs/source/examples/hybrid.rst | 173 ++++--- .../buildexe_package_manager.rst | 47 +- .../buildexe_script_example.rst | 34 +- docs/source/user_api/args.rst | 43 +- docs/source/user_api/register.rst | 21 +- example/buildexe/libs/build.main.cpp | 45 +- example/hybrid/custom_target/build.main.cpp | 47 +- example/hybrid/dep_chaining/build.cpp | 73 ++- example/hybrid/external_lib/build.main.cpp | 15 +- example/hybrid/foolib/build.main.cpp | 15 +- example/hybrid/generic/build.cpp | 102 ++-- example/hybrid/pch/build.cpp | 40 +- example/hybrid/simple/build.cpp | 42 +- example/hybrid/single/build.cpp | 21 +- example/hybrid/target_info/build.cpp | 74 ++- 34 files changed, 971 insertions(+), 832 deletions(-) diff --git a/bootstrap/include/bootstrap/build_buildcc.h b/bootstrap/include/bootstrap/build_buildcc.h index 340066a5..7dcb9aee 100644 --- a/bootstrap/include/bootstrap/build_buildcc.h +++ b/bootstrap/include/bootstrap/build_buildcc.h @@ -59,9 +59,8 @@ class BuildBuildCC { static constexpr const char *const kBuildccLibName = "libbuildcc"; public: - BuildBuildCC(Register ®, const BaseToolchain &toolchain, - const TargetEnv &env) - : reg_(reg), toolchain_(toolchain), env_(env) {} + BuildBuildCC(const BaseToolchain &toolchain, const TargetEnv &env) + : toolchain_(toolchain), env_(env) {} BuildBuildCC(const BuildBuildCC &) = delete; void Setup(const ArgToolchainState &state); @@ -75,7 +74,6 @@ class BuildBuildCC { } private: - Register ®_; const BaseToolchain &toolchain_; TargetEnv env_; diff --git a/bootstrap/include/bootstrap/build_tpl.h b/bootstrap/include/bootstrap/build_tpl.h index 9695f7d3..9d00cc5e 100644 --- a/bootstrap/include/bootstrap/build_tpl.h +++ b/bootstrap/include/bootstrap/build_tpl.h @@ -21,13 +21,7 @@ namespace buildcc { -struct TplConfig { - TplConfig() = default; - - OsId os_id{OsId::Linux}; -}; - -void tpl_cb(BaseTarget &target, const TplConfig &config = TplConfig()); +void tpl_cb(BaseTarget &target); } // namespace buildcc diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index 7ee8afd6..9115346e 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -38,31 +38,32 @@ int main(int argc, char **argv) { .AddToolchain("host", "Host Toolchain", custom_toolchain_arg) .Parse(argc, argv); - Register reg; - reg.Clean(clean_cb); + Reg::Init(); + Reg::Call(Args::Clean()).Func(clean_cb); BaseToolchain toolchain = custom_toolchain_arg.ConstructToolchain(); + toolchain.Verify(); BuildBuildCC buildcc( - reg, toolchain, TargetEnv(Project::GetRootDir(), Project::GetBuildDir())); + toolchain, TargetEnv(Project::GetRootDir(), Project::GetBuildDir())); buildcc.Setup(custom_toolchain_arg.state); const auto &buildcc_lib = buildcc.GetBuildcc(); ExecutableTarget_generic buildcc_hybrid_simple_example( "buildcc_hybrid_simple_example", toolchain, "example/hybrid/simple"); - reg.Build(custom_toolchain_arg.state, hybrid_simple_example_cb, - buildcc_hybrid_simple_example, buildcc_lib); - reg.Dep(buildcc_hybrid_simple_example, buildcc_lib); + Reg::Toolchain(custom_toolchain_arg.state) + .Build(hybrid_simple_example_cb, buildcc_hybrid_simple_example, + buildcc_lib) + .Dep(buildcc_hybrid_simple_example, buildcc_lib); // Runners - reg.RunBuild(); - reg.RunTest(); + Reg::Run(); // - Clang Compile Commands plugin::ClangCompileCommands({&buildcc_lib}).Generate(); // - Plugin Graph - std::string output = reg.GetTaskflow().dump(); + std::string output = Reg::GetTaskflow().dump(); const bool saved = env::save_file("graph.dot", output, false); env::assert_fatal(saved, "Could not save graph.dot file"); diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index 0d367c3d..d5b111b6 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -131,7 +131,6 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, if constexpr (env::is_win()) { // TODO, Clang switch (target.GetToolchain().GetId()) { - case ToolchainId::Gcc: case ToolchainId::MinGW: { target.AddPreprocessorFlag("-DFMT_HEADER_ONLY=1"); target.AddPreprocessorFlag("-DSPDLOG_FMT_EXTERNAL"); @@ -147,7 +146,7 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, } } - if constexpr (env::is_linux()) { + if constexpr (env::is_linux() || env::is_unix() || env::is_clang()) { // TODO, Clang switch (target.GetToolchain().GetId()) { case ToolchainId::Gcc: { @@ -196,51 +195,41 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { TargetEnv(env_.GetTargetRootDir() / "third_party" / "flatbuffers", env_.GetTargetBuildDir())); - reg_.CallbackIf(state, global_flags_cb, flatc_exe, toolchain_); - reg_.Build(state, build_flatc_exe_cb, flatc_exe); - // Schema auto &schema_gen = storage_.Add( kSchemaGenName, kSchemaGenName, TargetEnv(env_.GetTargetRootDir() / "buildcc" / "schema", env_.GetTargetBuildDir() / toolchain_.GetName())); - reg_.Build(schema_gen_cb, schema_gen, flatc_exe); - reg_.Dep(schema_gen, flatc_exe); // Flatbuffers HO lib auto &flatbuffers_ho_lib = storage_.Add( kFlatbuffersHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "flatbuffers", env_.GetTargetBuildDir())); - reg_.CallbackIf(state, flatbuffers_ho_cb, flatbuffers_ho_lib); // CLI11 HO lib auto &cli11_ho_lib = storage_.Add( kCli11HoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "CLI11", env_.GetTargetBuildDir())); - reg_.CallbackIf(state, cli11_ho_cb, cli11_ho_lib); // fmt HO lib auto &fmt_ho_lib = storage_.Add( kFmtHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "fmt", env_.GetTargetBuildDir())); - reg_.CallbackIf(state, fmt_ho_cb, fmt_ho_lib); // spdlog HO lib auto &spdlog_ho_lib = storage_.Add( kSpdlogHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "spdlog", env_.GetTargetBuildDir())); - reg_.CallbackIf(state, spdlog_ho_cb, spdlog_ho_lib); // taskflow HO lib auto &taskflow_ho_lib = storage_.Add( kTaskflowHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "taskflow", env_.GetTargetBuildDir())); - reg_.CallbackIf(state, taskflow_ho_cb, taskflow_ho_lib); // Tiny-process-library lib // TODO, Make this a generic selection between StaticTarget and @@ -250,21 +239,31 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { TargetEnv(env_.GetTargetRootDir() / "third_party" / "tiny-process-library", env_.GetTargetBuildDir())); - reg_.CallbackIf(state, global_flags_cb, tpl_lib, toolchain_); - TplConfig tpl_config; - tpl_config.os_id = get_host_os(); - reg_.Build(state, tpl_cb, tpl_lib, tpl_config); + // BuildCC lib // TODO, Make this a generic selection between StaticTarget and // DynamicTarget auto &buildcc_lib = storage_.Add( kBuildccLibName, kBuildccLibName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "buildcc", env_.GetTargetBuildDir())); - reg_.CallbackIf(state, global_flags_cb, buildcc_lib, toolchain_); - reg_.Build(state, buildcc_cb, buildcc_lib, schema_gen, flatbuffers_ho_lib, - fmt_ho_lib, spdlog_ho_lib, cli11_ho_lib, taskflow_ho_lib, tpl_lib); - reg_.Dep(buildcc_lib, schema_gen); - reg_.Dep(buildcc_lib, tpl_lib); + + Reg::Toolchain(state) + .Func(global_flags_cb, flatc_exe, toolchain_) + .Build(build_flatc_exe_cb, flatc_exe) + .Build(schema_gen_cb, schema_gen, flatc_exe) + .Dep(schema_gen, flatc_exe) + .Func(flatbuffers_ho_cb, flatbuffers_ho_lib) + .Func(cli11_ho_cb, cli11_ho_lib) + .Func(fmt_ho_cb, fmt_ho_lib) + .Func(spdlog_ho_cb, spdlog_ho_lib) + .Func(taskflow_ho_cb, taskflow_ho_lib) + .Func(global_flags_cb, tpl_lib, toolchain_) + .Build(tpl_cb, tpl_lib) + .Func(global_flags_cb, buildcc_lib, toolchain_) + .Build(buildcc_cb, buildcc_lib, schema_gen, flatbuffers_ho_lib, + fmt_ho_lib, spdlog_ho_lib, cli11_ho_lib, taskflow_ho_lib, tpl_lib) + .Dep(buildcc_lib, schema_gen) + .Dep(buildcc_lib, tpl_lib); } } // namespace buildcc diff --git a/bootstrap/src/build_tpl.cpp b/bootstrap/src/build_tpl.cpp index 0bd53b14..847161b1 100644 --- a/bootstrap/src/build_tpl.cpp +++ b/bootstrap/src/build_tpl.cpp @@ -18,22 +18,17 @@ namespace buildcc { -void tpl_cb(BaseTarget &target, const TplConfig &config) { +void tpl_cb(BaseTarget &target) { target.AddSource("process.cpp"); target.AddIncludeDir(""); target.AddHeader("process.hpp"); - switch (config.os_id) { - case OsId::Win: + if constexpr (env::is_win()) { target.AddSource("process_win.cpp"); - break; - case OsId::Linux: - case OsId::Unix: - case OsId::Mac: + } + + if constexpr (env::is_linux() || env::is_unix() || env::is_clang()) { target.AddSource("process_unix.cpp"); - break; - default: - break; } target.Build(); diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index f26e006d..6cccb1f3 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -27,13 +27,14 @@ #include "toolchain/toolchain.h" +#include "target/common/target_config.h" + namespace fs = std::filesystem; namespace buildcc { /** - * @brief Toolchain State used by the Register module to selectively build or - * test targets + * @brief Toolchain State used to selectively build and test targets */ struct ArgToolchainState { bool build{false}; @@ -81,8 +82,15 @@ struct ArgToolchain { struct ArgTarget { ArgTarget(){}; - std::string compile_command{""}; - std::string link_command{""}; + TargetConfig GetTargetConfig() { + TargetConfig config; + config.compile_command = compile_command; + config.link_command = link_command; + return config; + } + + std::string compile_command; + std::string link_command; }; struct ArgCustom { @@ -91,56 +99,8 @@ struct ArgCustom { class Args { private: - class Instance { - public: - /** - * @brief Parse command line information to CLI11 - * - * @param argc from int main(int argc, char ** argv) - * @param argv from int main(int argc, char ** argv) - */ - static void Parse(int argc, const char *const *argv); - - /** - * @brief Add toolchain with a unique name and description - * - * @param out Receive the toolchain information through the CLI - * @param initial Set the default toolchain information as a fallback - */ - Instance &AddToolchain(const std::string &name, - const std::string &description, ArgToolchain &out, - const ArgToolchain &initial = ArgToolchain()); - - /** - * @brief Add toolchain with a unique name and description - * - * @param out Receive the toolchain information through the CLI - * @param initial Set the default toolchain information as a fallback - */ - Instance &AddTarget(const std::string &name, const std::string &description, - ArgTarget &out, const ArgTarget &initial = ArgTarget()); - - /** - * @brief Custom callback for data - * - * @param add_cb Add callback that exposes underlying CLI::App - */ - Instance &AddCustomCallback(const std::function &add_cb); - - /** - * @brief Add custom data - * - * @param data Derive from `buildcc::ArgCustom` and override the `Add` API - */ - Instance &AddCustomData(ArgCustom &data); - }; - - struct Internal { - Instance instance; - CLI::App app{"BuildCC Buildsystem"}; - CLI::App *toolchain{nullptr}; - CLI::App *target{nullptr}; - }; + class Instance; + struct Internal; public: Args() = delete; @@ -151,6 +111,8 @@ class Args { static void Deinit(); // Getters + static bool IsInit(); + static bool IsParsed(); static bool Clean(); static env::LogLevel GetLogLevel(); @@ -159,12 +121,64 @@ class Args { private: static void RootArgs(); - static CLI::App &Ref(); + static Internal &RefInternal(); + static CLI::App &RefApp(); private: static std::unique_ptr internal_; }; +class Args::Instance { +public: + /** + * @brief Parse command line information to CLI11 + * + * @param argc from int main(int argc, char ** argv) + * @param argv from int main(int argc, char ** argv) + */ + static void Parse(int argc, const char *const *argv); + + /** + * @brief Add toolchain with a unique name and description + * + * @param out Receive the toolchain information through the CLI + * @param initial Set the default toolchain information as a fallback + */ + Instance &AddToolchain(const std::string &name, + const std::string &description, ArgToolchain &out, + const ArgToolchain &initial = ArgToolchain()); + + /** + * @brief Add toolchain with a unique name and description + * + * @param out Receive the toolchain information through the CLI + * @param initial Set the default toolchain information as a fallback + */ + Instance &AddTarget(const std::string &name, const std::string &description, + ArgTarget &out, const ArgTarget &initial = ArgTarget()); + + /** + * @brief Custom callback for data + * + * @param add_cb Add callback that exposes underlying CLI::App + */ + Instance &AddCustomCallback(const std::function &add_cb); + + /** + * @brief Add custom data + * + * @param data Derive from `buildcc::ArgCustom` and override the `Add` API + */ + Instance &AddCustomData(ArgCustom &data); +}; + +struct Args::Internal { + Instance instance; + CLI::App app{"BuildCC Buildsystem"}; + CLI::App *toolchain{nullptr}; + CLI::App *target{nullptr}; +}; + } // namespace buildcc #endif diff --git a/buildcc/lib/args/include/args/register.h b/buildcc/lib/args/include/args/register.h index 110e5246..a52a08de 100644 --- a/buildcc/lib/args/include/args/register.h +++ b/buildcc/lib/args/include/args/register.h @@ -31,22 +31,41 @@ namespace buildcc { -class Register { +class Reg { +private: + class Instance; + class CallbackInstance; + class ToolchainInstance; + public: - Register() { Initialize(); } - Register(const Register &) = delete; + Reg() = delete; + Reg(const Reg &) = delete; + Reg(Reg &&) = delete; - /** - * @brief Folders and files that need to be cleaned when `clean == true` - */ - void Clean(const std::function &clean_cb); + static void Init(); + static void Deinit(); + static void Run(const std::function &post_build_cb = + std::function()); + static CallbackInstance Call(bool condition = true); + static ToolchainInstance Toolchain(const ArgToolchainState &condition); + + static const tf::Taskflow &GetTaskflow(); + +private: + static Instance &Ref(); + +private: + static std::unique_ptr instance_; +}; +class Reg::Instance { +public: /** * @brief Generic register callback with variable arguments * Can be used to organize code into functional chunks */ template - void Callback(const C &build_cb, Params &&...params) { + static void Callback(const C &build_cb, Params &&...params) { build_cb(std::forward(params)...); } @@ -56,43 +75,25 @@ class Register { * Can be used to add Toolchain-Target specific information */ template - void CallbackIf(bool expression, const C &build_cb, Params &&...params) { + static void CallbackIf(bool expression, const C &build_cb, + Params &&...params) { if (expression) { Callback(build_cb, std::forward(params)...); } } /** - * @brief Generic register callback that is run when `toolchain_state.build == - * true` - * Can be used to add Toolchain-Target specific information - */ - template - void CallbackIf(const ArgToolchainState &toolchain_state, const C &build_cb, - Params &&...params) { - CallbackIf(toolchain_state.build, build_cb, - std::forward(params)...); - } - - /** - * @brief Register the Target to be built + * @brief Reg::Instance for Target to be built */ template - void Build(const ArgToolchainState &toolchain_state, const C &build_cb, - BaseTarget &target, Params &&...params) { - tf::Task task; - CallbackIf( - toolchain_state, - [&](BaseTarget <arget, Params &&...lparams) { - build_cb(ltarget, std::forward(lparams)...); - task = BuildTargetTask(ltarget); - }, - target, std::forward(params)...); + void Build(const C &build_cb, BaseTarget &target, Params &&...params) { + build_cb(target, std::forward(params)...); + tf::Task task = BuildTargetTask(target); BuildStoreTask(target.GetUniqueId(), task); } /** - * @brief Register the generator to be built + * @brief Reg::Instance for Generator to be built */ template void Build(const C &build_cb, BaseGenerator &generator, Params &&...params) { @@ -103,7 +104,7 @@ class Register { /** * @brief Setup dependency between 2 Targets - * PreReq: Call `Register::Build` before calling `Register::Dep` + * PreReq: Call `Reg::Instance::Build` before calling `Reg::Instance::Dep` * * Target runs after dependency is built */ @@ -111,8 +112,8 @@ class Register { const internal::BuilderInterface &dependency); /** - * @brief Register the Target to be run - * PreReq: Call `Register::Build` before calling `Register::Test` + * @brief Instance the Target to be run + * PreReq: Call `Reg::Instance::Build` before calling `Reg::Instance::Test` * PreReq: Requires ArgToolchainState::build && ArgToolchainState::test to be * true * @@ -120,19 +121,18 @@ class Register { * We can add more fmt::format arguments using the TestConfig arguments * parameter */ - void Test(const ArgToolchainState &toolchain_state, - const std::string &command, const BaseTarget &target, + void Test(const std::string &command, const BaseTarget &target, const TestConfig &config = TestConfig()); /** * @brief Builds the targets that have been dynamically added through - * `Register::Build` + * `Reg::Instance::Build` */ void RunBuild(); /** * @brief Runs the targets that have been dynamically added through - * `Register::Test` + * `Reg::Instance::Test` */ void RunTest(); @@ -143,11 +143,6 @@ class Register { private: private: - void Initialize(); - - // Setup env:: defaults - void Env(); - // BuildTasks tf::Task BuildTargetTask(BaseTarget &target); tf::Task BuildGeneratorTask(BaseGenerator &generator); @@ -158,12 +153,71 @@ class Register { tf::Taskflow build_tf_{"Targets"}; std::unordered_map build_; - - // Tests std::unordered_map tests_; +}; + +class Reg::CallbackInstance { +public: + CallbackInstance(bool condition = true) : condition_(condition) {} - // - tf::Executor executor_; + // Duplicated code + template + CallbackInstance &Func(const C &cb, Params &&...params) { + Instance::CallbackIf(condition_, cb, std::forward(params)...); + return *this; + } + + template + CallbackInstance &Build(const C &build_cb, BaseGenerator &generator, + Params &&...params) { + if (condition_) { + Ref().Build(build_cb, generator, std::forward(params)...); + }; + return *this; + } + +private: + bool condition_; +}; + +class Reg::ToolchainInstance { +public: + ToolchainInstance(const ArgToolchainState &condition) + : condition_(condition) {} + + template + ToolchainInstance &Func(const C &cb, Params &&...params) { + Instance::CallbackIf(condition_.build, cb, std::forward(params)...); + return *this; + } + + template + ToolchainInstance &Build(const C &build_cb, BaseGenerator &generator, + Params &&...params) { + return BuildInternal(build_cb, generator, std::forward(params)...); + } + template + ToolchainInstance &Build(const C &build_cb, BaseTarget &target, + Params &&...params) { + return BuildInternal(build_cb, target, std::forward(params)...); + } + ToolchainInstance &Dep(const internal::BuilderInterface &target, + const internal::BuilderInterface &dependency); + ToolchainInstance &Test(const std::string &command, const BaseTarget &target, + const TestConfig &config = TestConfig()); + +private: + template + ToolchainInstance &BuildInternal(const C &build_cb, T &t, + Params &&...params) { + if (condition_.build) { + Ref().Build(build_cb, t, std::forward(params)...); + } + return *this; + } + +private: + ArgToolchainState condition_; }; } // namespace buildcc diff --git a/buildcc/lib/args/include/args/register/test_info.h b/buildcc/lib/args/include/args/register/test_info.h index 50d61f41..a2e25dc7 100644 --- a/buildcc/lib/args/include/args/register/test_info.h +++ b/buildcc/lib/args/include/args/register/test_info.h @@ -35,7 +35,7 @@ struct TestOutput { }; /** - * @brief Configure your Register::Test to get test output + * @brief Configure your `Reg::Instance::Test` to get test output * * @param output_type Select your output type (behaviour) * @param redirect_stdout User stdout redirection @@ -64,7 +64,7 @@ struct TestOutput { struct TestConfig { public: /** - * @brief Configure your Register::Test using TestConfig + * @brief Configure your `Reg::Instance::Test` using TestConfig * * @param arguments fmt::format args passed to test commands * @param working_directory Working directory from which the test runs diff --git a/buildcc/lib/args/mock/parse.cpp b/buildcc/lib/args/mock/parse.cpp index 53213201..db3a1c6f 100644 --- a/buildcc/lib/args/mock/parse.cpp +++ b/buildcc/lib/args/mock/parse.cpp @@ -6,7 +6,7 @@ namespace buildcc { void Args::Instance::Parse(int argc, const char *const *argv) { try { - Ref().parse(argc, argv); + RefApp().parse(argc, argv); } catch (const CLI::ParseError &e) { env::assert_fatal(e.what()); } diff --git a/buildcc/lib/args/mock/tasks.cpp b/buildcc/lib/args/mock/tasks.cpp index 939e0100..40bc8eec 100644 --- a/buildcc/lib/args/mock/tasks.cpp +++ b/buildcc/lib/args/mock/tasks.cpp @@ -4,20 +4,20 @@ namespace buildcc { -tf::Task Register::BuildTargetTask(BaseTarget &target) { +tf::Task Reg::Instance::BuildTargetTask(BaseTarget &target) { mock().actualCall(fmt::format("BuildTask_{}", target.GetName()).c_str()); return build_tf_.placeholder().name(target.GetUniqueId()); } -tf::Task Register::BuildGeneratorTask(BaseGenerator &generator) { +tf::Task Reg::Instance::BuildGeneratorTask(BaseGenerator &generator) { mock().actualCall( fmt::format("BuildGeneratorTask_{}", generator.GetName()).c_str()); return build_tf_.placeholder().name(generator.GetUniqueId()); } -void Register::RunBuild() {} +void Reg::Instance::RunBuild() {} -void Register::RunTest() { +void Reg::Instance::RunTest() { std::for_each(tests_.begin(), tests_.end(), [](const auto &p) { p.second.TestRunner(); }); } diff --git a/buildcc/lib/args/src/args.cpp b/buildcc/lib/args/src/args.cpp index 378bd7d4..0d10823c 100644 --- a/buildcc/lib/args/src/args.cpp +++ b/buildcc/lib/args/src/args.cpp @@ -18,6 +18,10 @@ namespace { +// Error messages +constexpr const char *const kArgsNotInit = + "Initialize Args using the Args::Init API"; + // Groups constexpr const char *const kRootGroup = "Root"; @@ -99,9 +103,10 @@ std::unique_ptr Args::internal_; Args::Instance &Args::Init() { if (!internal_) { internal_ = std::make_unique(); + auto &app = RefApp(); internal_->toolchain = - Ref().add_subcommand(kToolchainSubcommand, kToolchainDesc); - internal_->target = Ref().add_subcommand(kTargetSubcommand, kTargetDesc); + app.add_subcommand(kToolchainSubcommand, kToolchainDesc); + internal_->target = app.add_subcommand(kTargetSubcommand, kTargetDesc); RootArgs(); } return internal_->instance; @@ -109,6 +114,13 @@ Args::Instance &Args::Init() { void Args::Deinit() { internal_.reset(nullptr); } +bool Args::IsInit() { return static_cast(internal_); } +bool Args::IsParsed() { + if (!IsInit()) { + return false; + } + return RefApp().parsed(); +} bool Args::Clean() { return clean_; } env::LogLevel Args::GetLogLevel() { return loglevel_; } @@ -118,7 +130,7 @@ const fs::path &Args::GetProjectBuildDir() { return project_build_dir_; } // Private void Args::RootArgs() { - auto &app = Ref(); + auto &app = RefApp(); app.set_help_all_flag(kHelpAllParam, kHelpAllDesc); app.set_config(kConfigParam, "", kConfigDesc)->expected(kMinFiles, kMaxFiles); @@ -137,7 +149,11 @@ void Args::RootArgs() { ->required(); } -CLI::App &Args::Ref() { return internal_->app; } +Args::Internal &Args::RefInternal() { + env::assert_fatal(internal_ != nullptr, kArgsNotInit); + return *internal_; +} +CLI::App &Args::RefApp() { return RefInternal().app; } // Args::Instance @@ -151,9 +167,7 @@ Args::Instance &Args::Instance::AddToolchain(const std::string &name, const std::string &description, ArgToolchain &out, const ArgToolchain &initial) { - CLI::App *toolchain = internal_->toolchain; - env::assert_fatal(toolchain != nullptr, - "Initialize Args using the Args::Init API"); + CLI::App *toolchain = RefInternal().toolchain; CLI::App *t_user = toolchain->add_subcommand(name, description)->group(kToolchainGroup); t_user->add_flag(kToolchainBuildParam, out.state.build); @@ -186,9 +200,7 @@ Args::Instance &Args::Instance::AddTarget(const std::string &name, const std::string &description, ArgTarget &out, const ArgTarget &initial) { - CLI::App *target = internal_->target; - env::assert_fatal(target != nullptr, - "Initialize Args using the Args::Init API"); + CLI::App *target = RefInternal().target; CLI::App *targetuser = target->add_subcommand(name, description)->group(kTargetGroup); targetuser->add_option(kTargetCompileCommandParam, out.compile_command) @@ -200,13 +212,13 @@ Args::Instance &Args::Instance::AddTarget(const std::string &name, Args::Instance &Args::Instance::AddCustomCallback( const std::function &add_cb) { - auto &app = Ref(); + auto &app = RefApp(); add_cb(app); return *this; } Args::Instance &Args::Instance::AddCustomData(ArgCustom &data) { - auto &app = Ref(); + auto &app = RefApp(); data.Add(app); return *this; } diff --git a/buildcc/lib/args/src/parse.cpp b/buildcc/lib/args/src/parse.cpp index bbb6b745..0d2aa186 100644 --- a/buildcc/lib/args/src/parse.cpp +++ b/buildcc/lib/args/src/parse.cpp @@ -19,7 +19,7 @@ namespace buildcc { void Args::Instance::Parse(int argc, const char *const *argv) { - auto &app = Ref(); + auto &app = RefApp(); try { app.parse(argc, argv); } catch (const CLI::ParseError &e) { diff --git a/buildcc/lib/args/src/register.cpp b/buildcc/lib/args/src/register.cpp index cbd1e719..dd042ae3 100644 --- a/buildcc/lib/args/src/register.cpp +++ b/buildcc/lib/args/src/register.cpp @@ -26,6 +26,11 @@ namespace fs = std::filesystem; +namespace { +constexpr const char *const kRegkNotInit = + "Initialize Reg using the Reg::Init API"; +} + namespace { void DepDetectDuplicate(const tf::Task &target_task, const std::string &match) { @@ -60,24 +65,80 @@ void DepDetectCyclicDependency(const tf::Task &target_task, namespace buildcc { -void Register::Clean(const std::function &clean_cb) { - if (Args::Clean()) { - clean_cb(); +std::unique_ptr Reg::instance_; + +void Reg::Init() { + if (!instance_) { + instance_ = std::make_unique(); + env::assert_fatal(Args::IsParsed(), "Setup your Args"); + Project::Init(fs::current_path() / Args::GetProjectRootDir(), + fs::current_path() / Args::GetProjectBuildDir()); + env::set_log_level(Args::GetLogLevel()); + } +} + +void Reg::Deinit() { + instance_.reset(nullptr); + Project::Deinit(); +} + +void Reg::Run(const std::function &post_build_cb) { + auto &ref = Ref(); + ref.RunBuild(); + if (post_build_cb) { + post_build_cb(); + } + ref.RunTest(); +} + +const tf::Taskflow &Reg::GetTaskflow() { return Ref().GetTaskflow(); } + +Reg::Instance &Reg::Ref() { + env::assert_fatal(instance_ != nullptr, kRegkNotInit); + return *instance_; +} + +// Reg::ToolchainInstance + +Reg::ToolchainInstance Reg::Toolchain(const ArgToolchainState &condition) { + env::assert_fatal(instance_ != nullptr, kRegkNotInit); + return ToolchainInstance(condition); +} + +Reg::ToolchainInstance & +Reg::ToolchainInstance::Dep(const internal::BuilderInterface &target, + const internal::BuilderInterface &dependency) { + if (condition_.build) { + Ref().Dep(target, dependency); + } + return *this; +} + +Reg::ToolchainInstance &Reg::ToolchainInstance::Test(const std::string &command, + const BaseTarget &target, + const TestConfig &config) { + if (condition_.build && condition_.test) { + Ref().Test(command, target, config); } + return *this; +} + +// Reg::CallbackInstance + +Reg::CallbackInstance Reg::Call(bool condition) { + env::assert_fatal(instance_ != nullptr, kRegkNotInit); + return CallbackInstance(condition); } -void Register::Dep(const internal::BuilderInterface &target, - const internal::BuilderInterface &dependency) { +// Reg::Instance + +void Reg::Instance::Dep(const internal::BuilderInterface &target, + const internal::BuilderInterface &dependency) { const auto target_iter = build_.find(target.GetUniqueId()); const auto dep_iter = build_.find(dependency.GetUniqueId()); env::assert_fatal(!(target_iter == build_.end() || dep_iter == build_.end()), - "Call Register::Build API on target and " - "dependency before Register::Dep API"); - - // empty tasks -> not built so skip - if (target_iter->second.empty() || dep_iter->second.empty()) { - return; - } + "Call Instance::Build API on target and " + "dependency before Instance::Dep API"); const std::string &dep_unique_id = dependency.GetUniqueId(); DepDetectDuplicate(target_iter->second, dep_unique_id); @@ -87,17 +148,12 @@ void Register::Dep(const internal::BuilderInterface &target, target_iter->second.succeed(dep_iter->second); } -void Register::Test(const ArgToolchainState &toolchain_state, - const std::string &command, const BaseTarget &target, - const TestConfig &config) { - if (!(toolchain_state.build && toolchain_state.test)) { - return; - } - +void Reg::Instance::Test(const std::string &command, const BaseTarget &target, + const TestConfig &config) { const auto target_iter = build_.find(target.GetUniqueId()); env::assert_fatal( !(target_iter == build_.end()), - "Call Register::Build API on target before Register::Test API"); + "Call Instance::Build API on target before Instance::Test API"); const bool added = tests_.emplace(target.GetUniqueId(), TestInfo(target, command, config)) @@ -108,22 +164,14 @@ void Register::Test(const ArgToolchainState &toolchain_state, // Private -void Register::BuildStoreTask(const std::string &unique_id, - const tf::Task &task) { +void Reg::Instance::BuildStoreTask(const std::string &unique_id, + const tf::Task &task) { const bool stored = build_.emplace(unique_id, task).second; env::assert_fatal( - stored, fmt::format("Duplicate `Register::Build` call detected for '{}'", + stored, fmt::format("Duplicate `Instance::Build` call detected for '{}'", unique_id)); } -void Register::Initialize() { Env(); } - -void Register::Env() { - Project::Init(fs::current_path() / Args::GetProjectRootDir(), - fs::current_path() / Args::GetProjectBuildDir()); - env::set_log_level(Args::GetLogLevel()); -} - // void TestInfo::TestRunner() const { diff --git a/buildcc/lib/args/src/tasks.cpp b/buildcc/lib/args/src/tasks.cpp index 97e9cc4a..054b8eed 100644 --- a/buildcc/lib/args/src/tasks.cpp +++ b/buildcc/lib/args/src/tasks.cpp @@ -20,32 +20,34 @@ namespace buildcc { -tf::Task Register::BuildTargetTask(BaseTarget &target) { +tf::Task Reg::Instance::BuildTargetTask(BaseTarget &target) { return build_tf_.composed_of(target.GetTaskflow()).name(target.GetUniqueId()); } -tf::Task Register::BuildGeneratorTask(BaseGenerator &generator) { +tf::Task Reg::Instance::BuildGeneratorTask(BaseGenerator &generator) { return build_tf_.composed_of(generator.GetTaskflow()) .name(generator.GetUniqueId()); } -void Register::RunBuild() { - env::log_info(__FUNCTION__, fmt::format("Running with {} workers", - executor_.num_workers())); - executor_.run(build_tf_); - executor_.wait_for_all(); +void Reg::Instance::RunBuild() { + tf::Executor executor; + env::log_info(__FUNCTION__, + fmt::format("Running with {} workers", executor.num_workers())); + executor.run(build_tf_); + executor.wait_for_all(); env::assert_fatal(env::get_task_state() == env::TaskState::SUCCESS, "Task state is not successful!"); } -void Register::RunTest() { +void Reg::Instance::RunTest() { tf::Taskflow test_tf{"Tests"}; test_tf.for_each( tests_.begin(), tests_.end(), [](const std::pair &p) { p.second.TestRunner(); }); - executor_.run(test_tf); - executor_.wait_for_all(); + tf::Executor executor; + executor.run(test_tf); + executor.wait_for_all(); } } // namespace buildcc diff --git a/buildcc/lib/args/test/test_args.cpp b/buildcc/lib/args/test/test_args.cpp index 697df743..8b519174 100644 --- a/buildcc/lib/args/test/test_args.cpp +++ b/buildcc/lib/args/test/test_args.cpp @@ -19,6 +19,9 @@ TEST(ArgsTestGroup, Args_BasicParse) { std::vector av{"", "--config", "configs/basic_parse.toml"}; int argc = av.size(); + CHECK_FALSE(buildcc::Args::IsInit()); + CHECK_FALSE(buildcc::Args::IsParsed()); + (void)buildcc::Args::Init(); auto &instance = buildcc::Args::Init(); // Second init does nothing when // already initialized @@ -28,6 +31,8 @@ TEST(ArgsTestGroup, Args_BasicParse) { STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); CHECK_TRUE(buildcc::Args::Clean()); + CHECK_TRUE(buildcc::Args::IsInit()); + CHECK_TRUE(buildcc::Args::IsParsed()); } TEST(ArgsTestGroup, Args_BasicExit) { diff --git a/buildcc/lib/args/test/test_register.cpp b/buildcc/lib/args/test/test_register.cpp index bcd6b191..2403876c 100644 --- a/buildcc/lib/args/test/test_register.cpp +++ b/buildcc/lib/args/test/test_register.cpp @@ -15,6 +15,7 @@ TEST_GROUP(RegisterTestGroup) { void teardown() { + buildcc::Reg::Deinit(); buildcc::Args::Deinit(); mock().clear(); } @@ -32,7 +33,8 @@ TEST(RegisterTestGroup, Register_Initialize) { CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); CHECK_TRUE(buildcc::Args::Clean()); - buildcc::Register reg; + buildcc::Reg::Init(); + buildcc::Reg::Init(); // Second init does nothing } TEST(RegisterTestGroup, Register_Clean) { @@ -47,9 +49,12 @@ TEST(RegisterTestGroup, Register_Clean) { CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); CHECK_TRUE(buildcc::Args::Clean()); - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectOneCall("CleanCb"); - reg.Clean([]() { mock().actualCall("CleanCb"); }); + buildcc::Reg::Call(buildcc::Args::Clean()).Func([]() { + mock().actualCall("CleanCb"); + }); + buildcc::Reg::Deinit(); buildcc::Args::Deinit(); } @@ -70,8 +75,11 @@ TEST(RegisterTestGroup, Register_Clean) { CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); CHECK_FALSE(buildcc::Args::Clean()); - buildcc::Register reg; - reg.Clean([]() { mock().actualCall("CleanCb"); }); + buildcc::Reg::Init(); + buildcc::Reg::Call(buildcc::Args::Clean()).Func([]() { + mock().actualCall("CleanCb"); + }); + buildcc::Reg::Deinit(); buildcc::Args::Deinit(); } @@ -108,18 +116,65 @@ TEST(RegisterTestGroup, Register_Build) { { buildcc::ArgToolchainState state{false, false}; - buildcc::Register reg; - reg.Build( - state, [](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Init(); + buildcc::Reg::Toolchain(state).Build( + [](buildcc::BaseTarget &target) { (void)target; }, target); + (void)buildcc::Reg::GetTaskflow(); + buildcc::Reg::Deinit(); + CHECK_THROWS(std::exception, buildcc::Reg::GetTaskflow()); } { buildcc::ArgToolchainState state{true, true}; - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); - reg.Build( - state, [](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(state).Build( + [](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Deinit(); + } + + buildcc::Project::Deinit(); + mock().checkExpectations(); +} + +TEST(RegisterTestGroup, Register_Run_PostCb) { + std::vector av{ + "", + "--config", + "configs/basic_parse.toml", + }; + int argc = av.size(); + + buildcc::ArgToolchain gcc_toolchain; + buildcc::ArgToolchain msvc_toolchain; + buildcc::Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", gcc_toolchain) + .AddToolchain("msvc", "Generic msvc toolchain", msvc_toolchain) + .Parse(argc, av.data()); + + STRCMP_EQUAL(buildcc::Args::GetProjectRootDir().string().c_str(), "root"); + STRCMP_EQUAL(buildcc::Args::GetProjectBuildDir().string().c_str(), "build"); + CHECK(buildcc::Args::GetLogLevel() == buildcc::env::LogLevel::Trace); + CHECK_TRUE(buildcc::Args::Clean()); + + // Make dummy toolchain and target + buildcc::Project::Init(fs::current_path(), fs::current_path()); + buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", + ""); + buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, + toolchain, ""); + + { + buildcc::ArgToolchainState state{false, false}; + + buildcc::Reg::Init(); + buildcc::Reg::Toolchain(state).Build( + [](buildcc::BaseTarget &target) { (void)target; }, target); + + mock().expectOneCall("Build_PostCb"); + buildcc::Reg::Run([]() { mock().actualCall("Build_PostCb"); }); + buildcc::Reg::Deinit(); } buildcc::Project::Deinit(); @@ -167,43 +222,48 @@ TEST(RegisterTestGroup, Register_NoBuildAndDep) { // T0D0 { - buildcc::Register reg; - CHECK_THROWS(std::exception, reg.Dep(target, dependency)); + buildcc::Reg::Init(); + CHECK_THROWS(std::exception, + buildcc::Reg::Toolchain(trueState).Dep(target, dependency)); + buildcc::Reg::Deinit(); } // T0D1 { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_depT"); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, dependency); - CHECK_THROWS(std::exception, reg.Dep(target, dependency)); + CHECK_THROWS(std::exception, + buildcc::Reg::Toolchain(trueState).Dep(target, dependency)); + buildcc::Reg::Deinit(); } // T1D0 { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, target); - CHECK_THROWS(std::exception, reg.Dep(target, dependency)); + CHECK_THROWS(std::exception, + buildcc::Reg::Toolchain(trueState).Dep(target, dependency)); + buildcc::Reg::Deinit(); } // T1D1 { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, target); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, dependency); - reg.Dep(target, dependency); + buildcc::Reg::Toolchain(trueState).Dep(target, dependency); + buildcc::Reg::Deinit(); } buildcc::Project::Deinit(); @@ -251,54 +311,56 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { // T0D0 { - buildcc::Register reg; - reg.Build( - falseState, [](buildcc::BaseTarget &target) { (void)target; }, target); - reg.Build( - falseState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency); - - reg.Dep(target, dependency); + buildcc::Reg::Init(); + buildcc::Reg::Toolchain(falseState) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target) + .Build([](buildcc::BaseTarget &target) { (void)target; }, dependency) + .Dep(target, dependency); + buildcc::Reg::Deinit(); } // T0D1 { - buildcc::Register reg; - reg.Build( - falseState, [](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Init(); + buildcc::Reg::Toolchain(falseState) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target); mock().expectNCalls(1, "BuildTask_depT"); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency); - - reg.Dep(target, dependency); + // In this case, target is not built so Dep throws + // Bad usage + CHECK_THROWS(std::exception, + buildcc::Reg::Toolchain(trueState) + .Build([](buildcc::BaseTarget &target) { (void)target; }, + dependency) + .Dep(target, dependency)); + buildcc::Reg::Deinit(); } // T1D0 { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, target); - reg.Build( - falseState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(falseState) + .Build([](buildcc::BaseTarget &target) { (void)target; }, dependency); - reg.Dep(target, dependency); + // In this case dependency is not built + // Bad usage + CHECK_THROWS(std::exception, + buildcc::Reg::Toolchain(trueState).Dep(target, dependency)); + buildcc::Reg::Deinit(); } // T1D1 { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, target); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency); - - reg.Dep(target, dependency); + buildcc::Reg::Toolchain(trueState) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target) + .Build([](buildcc::BaseTarget &target) { (void)target; }, dependency) + .Dep(target, dependency); + buildcc::Reg::Deinit(); } buildcc::Project::Deinit(); @@ -340,41 +402,41 @@ TEST(RegisterTestGroup, Register_DepDuplicate) { // Duplicate dependency with 2 Targets { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, target); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency); - - reg.Dep(target, dependency); - CHECK_THROWS(std::exception, reg.Dep(target, dependency)); + buildcc::Reg::Toolchain(trueState) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target) + .Build([](buildcc::BaseTarget &target) { (void)target; }, dependency) + .Dep(target, dependency); + CHECK_THROWS(std::exception, + buildcc::Reg::Toolchain(trueState).Dep(target, dependency)); + buildcc::Reg::Deinit(); } // Duplicate dependency with 3 Targets { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); mock().expectNCalls(1, "BuildTask_dep2T"); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, target); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency2); - - reg.Dep(dependency, dependency2); - reg.Dep(target, dependency); - reg.Dep(target, dependency2); - - CHECK_THROWS(std::exception, reg.Dep(target, dependency)); - CHECK_THROWS(std::exception, reg.Dep(target, dependency2)); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, dependency); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, dependency2); + + buildcc::Reg::Toolchain(trueState).Dep(dependency, dependency2); + buildcc::Reg::Toolchain(trueState).Dep(target, dependency); + buildcc::Reg::Toolchain(trueState).Dep(target, dependency2); + + CHECK_THROWS(std::exception, + buildcc::Reg::Toolchain(trueState).Dep(target, dependency)); + CHECK_THROWS(std::exception, + buildcc::Reg::Toolchain(trueState).Dep(target, dependency2)); + buildcc::Reg::Deinit(); } buildcc::Project::Deinit(); @@ -416,40 +478,41 @@ TEST(RegisterTestGroup, Register_DepCyclic) { // Immediate cyclic depdendency { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, target); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency); - - reg.Dep(target, dependency); - CHECK_THROWS(std::exception, reg.Dep(dependency, target)); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, dependency); + + buildcc::Reg::Toolchain(trueState).Dep(target, dependency); + CHECK_THROWS(std::exception, + buildcc::Reg::Toolchain(trueState).Dep(dependency, target)); + buildcc::Reg::Deinit(); } // Duplicate dependency with 3 Targets { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); mock().expectNCalls(1, "BuildTask_depT"); mock().expectNCalls(1, "BuildTask_dep2T"); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, target); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency); - reg.Build( - trueState, [](buildcc::BaseTarget &target) { (void)target; }, - dependency2); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, dependency); + buildcc::Reg::Toolchain(trueState).Build( + [](buildcc::BaseTarget &target) { (void)target; }, dependency2); - reg.Dep(dependency, dependency2); - reg.Dep(target, dependency); + buildcc::Reg::Toolchain(trueState).Dep(dependency, dependency2); + buildcc::Reg::Toolchain(trueState).Dep(target, dependency); // dependency2 -> dependency -> target -> dependency2 - CHECK_THROWS(std::exception, reg.Dep(dependency2, target)); + CHECK_THROWS(std::exception, + buildcc::Reg::Toolchain(trueState).Dep(dependency2, target)); + buildcc::Reg::Deinit(); } buildcc::Project::Deinit(); @@ -498,43 +561,48 @@ TEST(RegisterTestGroup, Register_Test) { // FF { - buildcc::Register reg; - reg.Test(stateFail, "{executable}", target); + buildcc::Reg::Init(); + buildcc::Reg::Toolchain(stateFail).Test("{executable}", target); + buildcc::Reg::Deinit(); } // TF { - buildcc::Register reg; - reg.Test(state1, "{executable}", target); + buildcc::Reg::Init(); + buildcc::Reg::Toolchain(state1).Test("{executable}", target); + buildcc::Reg::Deinit(); } // FT { - buildcc::Register reg; - reg.Test(state2, "{executable}", target); + buildcc::Reg::Init(); + buildcc::Reg::Toolchain(state2).Test("{executable}", target); + buildcc::Reg::Deinit(); } // TT - // Register::Build not called + // Reg::Instance::Build not called { - buildcc::Register reg; - CHECK_THROWS(std::exception, - reg.Test(stateSuccess, "{executable}", target)); + buildcc::Reg::Init(); + CHECK_THROWS( + std::exception, + buildcc::Reg::Toolchain(stateSuccess).Test("{executable}", target)); + buildcc::Reg::Deinit(); } // Correct Usage { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); - reg.Build( - stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, - target); - reg.Test(stateSuccess, "{executable}", target); + buildcc::Reg::Toolchain(stateSuccess) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(stateSuccess).Test("{executable}", target); std::vector stdout_data; std::vector stderr_data; buildcc::env::m::CommandExpect_Execute(1, true, &stdout_data, &stderr_data); - reg.RunTest(); + buildcc::Reg::Run(); + buildcc::Reg::Deinit(); } buildcc::Project::Deinit(); @@ -575,105 +643,111 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { // TestOutput::Type::DefaultBehaviour { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); - reg.Build( - stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, - target); - reg.Test( - stateSuccess, "{executable}", target, - buildcc::TestConfig( - {}, {}, - buildcc::TestOutput(buildcc::TestOutput::Type::DefaultBehaviour))); + buildcc::Reg::Toolchain(stateSuccess) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(stateSuccess) + .Test("{executable}", target, + buildcc::TestConfig( + {}, {}, + buildcc::TestOutput( + buildcc::TestOutput::Type::DefaultBehaviour))); buildcc::env::m::CommandExpect_Execute(1, true); - reg.RunTest(); + buildcc::Reg::Run(); + buildcc::Reg::Deinit(); } // TestOutput::Type::TestPrintOnStderr { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); - reg.Build( - stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, - target); - reg.Test( - stateSuccess, "{executable}", target, - buildcc::TestConfig( - {}, {}, - buildcc::TestOutput(buildcc::TestOutput::Type::TestPrintOnStderr))); + buildcc::Reg::Toolchain(stateSuccess) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(stateSuccess) + .Test("{executable}", target, + buildcc::TestConfig( + {}, {}, + buildcc::TestOutput( + buildcc::TestOutput::Type::TestPrintOnStderr))); std::vector stderr_data; buildcc::env::m::CommandExpect_Execute(1, true, nullptr, &stderr_data); - reg.RunTest(); + buildcc::Reg::Run(); + buildcc::Reg::Deinit(); } // TestOutput::Type::TestPrintOnStdout { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); - reg.Build( - stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, - target); - reg.Test( - stateSuccess, "{executable}", target, - buildcc::TestConfig( - {}, {}, - buildcc::TestOutput(buildcc::TestOutput::Type::TestPrintOnStdout))); + buildcc::Reg::Toolchain(stateSuccess) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(stateSuccess) + .Test("{executable}", target, + buildcc::TestConfig( + {}, {}, + buildcc::TestOutput( + buildcc::TestOutput::Type::TestPrintOnStdout))); std::vector stdout_data; buildcc::env::m::CommandExpect_Execute(1, true, &stdout_data, nullptr); - reg.RunTest(); + buildcc::Reg::Run(); + buildcc::Reg::Deinit(); } // TestOutput::Type::TestPrintOnStderrAndStdout { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); - reg.Build( - stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, - target); - reg.Test(stateSuccess, "{executable}", target, - buildcc::TestConfig( - {}, {}, - buildcc::TestOutput( - buildcc::TestOutput::Type::TestPrintOnStderrAndStdout))); + buildcc::Reg::Toolchain(stateSuccess) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(stateSuccess) + .Test("{executable}", target, + buildcc::TestConfig( + {}, {}, + buildcc::TestOutput( + buildcc::TestOutput::Type::TestPrintOnStderrAndStdout))); std::vector stdout_data; std::vector stderr_data; buildcc::env::m::CommandExpect_Execute(1, true, &stdout_data, &stderr_data); - reg.RunTest(); + buildcc::Reg::Run(); + buildcc::Reg::Deinit(); } // TestOutput::Type::UserRedirect { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); - reg.Build( - stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, - target); - reg.Test(stateSuccess, "{executable}", target, - buildcc::TestConfig( - {}, {}, - buildcc::TestOutput(buildcc::TestOutput::Type::UserRedirect, - nullptr, nullptr))); + buildcc::Reg::Toolchain(stateSuccess) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(stateSuccess) + .Test("{executable}", target, + buildcc::TestConfig( + {}, {}, + buildcc::TestOutput(buildcc::TestOutput::Type::UserRedirect, + nullptr, nullptr))); buildcc::env::m::CommandExpect_Execute(1, true); - reg.RunTest(); + buildcc::Reg::Run(); + buildcc::Reg::Deinit(); } // TestOutput::Type::UserRedirect { - buildcc::Register reg; + buildcc::Reg::Init(); mock().expectNCalls(1, "BuildTask_dummyT"); - reg.Build( - stateSuccess, [](buildcc::BaseTarget &target) { (void)target; }, - target); - reg.Test( - stateSuccess, "{executable}", target, - buildcc::TestConfig( - {}, {}, buildcc::TestOutput(buildcc::TestOutput::Type(65535)))); - CHECK_THROWS(std::exception, reg.RunTest()); + buildcc::Reg::Toolchain(stateSuccess) + .Build([](buildcc::BaseTarget &target) { (void)target; }, target); + buildcc::Reg::Toolchain(stateSuccess) + .Test( + "{executable}", target, + buildcc::TestConfig( + {}, {}, buildcc::TestOutput(buildcc::TestOutput::Type(65535)))); + CHECK_THROWS(std::exception, buildcc::Reg::Run()); + buildcc::Reg::Deinit(); } buildcc::Project::Deinit(); diff --git a/buildexe/buildexe.cpp b/buildexe/buildexe.cpp index 0af85b3f..16549953 100644 --- a/buildexe/buildexe.cpp +++ b/buildexe/buildexe.cpp @@ -53,8 +53,8 @@ int main(int argc, char **argv) { // TODO, Add libraries (git cloned) // TODO, Add extension (git cloned) - Register reg; - reg.Clean(clean_cb); + Reg::Init(); + Reg::Call(Args::Clean()).Func(clean_cb); // Host Toolchain BaseToolchain toolchain = @@ -66,7 +66,7 @@ int main(int argc, char **argv) { } // Build Target - BuildEnvSetup build_setup(reg, toolchain, buildexe_args); + BuildEnvSetup build_setup(toolchain, buildexe_args); build_setup.ConstructTarget(); // Run Target if script mode diff --git a/buildexe/include/buildexe/build_env_setup.h b/buildexe/include/buildexe/build_env_setup.h index d73c9e9c..e36983d4 100644 --- a/buildexe/include/buildexe/build_env_setup.h +++ b/buildexe/include/buildexe/build_env_setup.h @@ -31,9 +31,9 @@ class BuildEnvSetup { static constexpr const char *const kUserTargetName = "UserTarget"; public: - BuildEnvSetup(Register ®, const BaseToolchain &toolchain, + BuildEnvSetup(const BaseToolchain &toolchain, const BuildExeArgs &buildexe_args) - : reg_(reg), toolchain_(toolchain), buildexe_args_(buildexe_args) { + : toolchain_(toolchain), buildexe_args_(buildexe_args) { state_.build = true; } @@ -62,7 +62,6 @@ class BuildEnvSetup { void DepUserTargetOnBuildcc(); private: - Register ®_; const BaseToolchain &toolchain_; const BuildExeArgs &buildexe_args_; diff --git a/buildexe/src/build_env_setup.cpp b/buildexe/src/build_env_setup.cpp index 2bfcac96..72b17fba 100644 --- a/buildexe/src/build_env_setup.cpp +++ b/buildexe/src/build_env_setup.cpp @@ -29,7 +29,7 @@ void BuildEnvSetup::ConstructTarget() { // user target ConstructUserTarget(); } - reg_.RunBuild(); + Reg::Run(); } void BuildEnvSetup::RunUserTarget(const ArgScriptInfo &arg_script_info) { @@ -76,7 +76,7 @@ void BuildEnvSetup::ConstructUserTargetWithBuildcc() { void BuildEnvSetup::BuildccTargetSetup() { const fs::path &buildcc_base = BuildccHome::GetBuildccBaseDir(); auto &buildcc_package = storage_.Add( - kBuildccPackageName, reg_, toolchain_, + kBuildccPackageName, toolchain_, TargetEnv(buildcc_base, buildcc_base / "_build_exe")); buildcc_package.Setup(state_); } @@ -206,12 +206,12 @@ struct BuildExeLibDir {{ } void BuildEnvSetup::UserTargetBuild() { - reg_.Build( - state_, [](BaseTarget &target) { target.Build(); }, GetUserTarget()); + Reg::Toolchain(state_).Build([](BaseTarget &target) { target.Build(); }, + GetUserTarget()); } void BuildEnvSetup::DepUserTargetOnBuildcc() { - reg_.Dep(GetUserTarget(), GetBuildcc()); + Reg::Toolchain(state_).Dep(GetUserTarget(), GetBuildcc()); } } // namespace buildcc diff --git a/docs/source/examples/hybrid.rst b/docs/source/examples/hybrid.rst index abc73c73..38c611a8 100644 --- a/docs/source/examples/hybrid.rst +++ b/docs/source/examples/hybrid.rst @@ -14,20 +14,18 @@ We are only using a single Toolchain - Target pair :linenos: int main(int argc, char ** argv) { - // Args module to get data from the command line or .toml file passed in through --config - Args args; - // Register your [toolchain.{name}] // In this case it will be [toolchain.gcc] ArgToolchain arg_gcc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - // Parse the arguments from the command line - args.Parse(argc, argv); + // Args module to get data from the command line or .toml file passed in through --config + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .Parse(argc, argv); // Register module - Register reg(args); - reg.Clean(clean_cb); + Reg::Init(); + Reg::Call(Args::Clean()).Func(clean_cb); // TODO, Write your target builds here // See examples below @@ -75,14 +73,13 @@ Compile a single source with a single GCC compiler. ExecutableTarget_gcc hello_world("hello_world", gcc, ""); // Select your builds and tests using the .toml files - reg.Build(arg_gcc.state, hello_world_build_cb, hello_world); - reg.Test(arg_gcc.state, "{executable}", hello_world); + Reg::Toolchain(arg_gcc.state) + .Func([&]() { gcc.Verify(); }) + .Build(arg_gcc.state, hello_world_build_cb, hello_world) + .Test(arg_gcc.state, "{executable}", hello_world); - // Build Target - reg.RunBuild(); - - // Test Target - reg.RunTest(); + // Build and Test Target + Reg::Run(); } static void hello_world_build_cb(BaseTarget &target) { @@ -100,23 +97,21 @@ We are using multiple Toolchain - Target pairs :linenos: int main(int argc, char ** argv) { - // Args module to get data from the command line or .toml file passed in through --config - Args args; - // Register your [toolchain.{name}] // In this case it will be [toolchain.gcc] and [toolchain.msvc] ArgToolchain arg_gcc; ArgToolchain arg_msvc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - // NOTE, You can add more toolchains here as per your project requirement - // Parse the arguments from the command line - args.Parse(argc, argv); + // Args module to get data from the command line or .toml file passed in through --config + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) + .Parse(argc, argv); + // NOTE, You can add more toolchains here as per your project requirement // Register module - Register reg(args); - reg.Clean(clean_cb); + Reg::Init(); + Reg::Call(Args::Clean()).Func(clean_cb); // TODO, Write your target builds here // See examples below @@ -167,30 +162,30 @@ Similar to lowlevel GCC Flags example for both the GCC and MSVC compiler // See Multiple Boilerplate Toolchain_gcc gcc; - Toolchain_msvc msvc; - ExecutableTarget_gcc g_cppflags("cppflags", gcc, "files"); - ExecutableTarget_msvc m_cppflags("cppflags", msvc, "files"); ExecutableTarget_gcc g_cflags("cflags", gcc, "files"); + // Select your builds and tests using the .toml files + Reg::Toolchain(arg_gcc.state) + .Func([&](){ gcc.Verify(); }) + .Build(cppflags_build_cb, g_cppflags) + .Build(cflags_build_cb, g_cflags) + .Test("{executable}", g_cppflags) + .Test("{executable}", g_cflags); + + Toolchain_msvc msvc; + ExecutableTarget_msvc m_cppflags("cppflags", msvc, "files"); ExecutableTarget_msvc m_cflags("cflags", msvc, "files"); + Reg::Toolchain(arg_msvc.state) + .Func([&](){ msvc.Verify(); }) + .Build(cppflags_build_cb, m_cppflags) + .Build(cflags_build_cb, m_cflags) + .Test("{executable}", m_cppflags) + .Test("{executable}", m_cflags); - // Select your builds and tests using the .toml files - reg.Build(arg_gcc.state, cppflags_build_cb, g_cppflags); - reg.Build(arg_msvc.state, cppflags_build_cb, m_cppflags); - reg.Build(arg_gcc.state, cflags_build_cb, g_cflags); - reg.Build(arg_msvc.state, cflags_build_cb, m_cflags); - - // Test steps - reg.Test(arg_gcc.state, "{executable}", g_cppflags); - reg.Test(arg_msvc.state, "{executable}", m_cppflags); - reg.Test(arg_gcc.state, "{executable}", g_cflags); - reg.Test(arg_msvc.state, "{executable}", m_cflags); - - // Build Target - reg.RunBuild(); - - // Test Target - reg.RunTest(); + // Build and Test target + Reg::Run(); + + return 0; } static void cppflags_build_cb(BaseTarget &cppflags) { @@ -301,7 +296,6 @@ For end users consuming third party libraries .. code-block:: cpp :linenos: - :emphasize-lines: 18 #include "build.foo.h" @@ -312,13 +306,16 @@ For end users consuming third party libraries Toolchain_gcc gcc; Toolchain_msvc msvc; - ExecutableTarget_gcc g_foolib("foolib", gcc, ""); - ExecutableTarget_msvc m_foolib("foolib", msvc, ""); + ExecutableTarget_gcc g_foolib("foolib", gcc, TargetEnv("...")); + ExecutableTarget_msvc m_foolib("foolib", msvc, TargetEnv("..."); - reg.Build(arg_gcc.state, foolib_build_cb, g_foolib); - reg.Build(arg_msvc.state, foolib_build_cb, m_foolib); + Reg::Toolchain(arg_gcc.state) + .Build(foolib_build_cb, g_foolib); + + Reg::Toolchain(arg_msvc.state) + .Build(foolib_build_cb, m_foolib); - reg.RunBuild(); + Reg::Run(); } static void foolib_build_cb(BaseTarget &target) { @@ -334,48 +331,43 @@ For super customized targets and toolchains .. code-block:: cpp :linenos: - :emphasize-lines: 12,13,30,34,35,36 int main(int argc, char ** argv) { - Args args; ArgToolchain arg_gcc; ArgToolchain arg_msvc; ArgToolchain toolchain_clang_gnu; ArgTarget target_clang_gnu; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.AddToolchain("msvc", "Generic msvc toolchain", arg_msvc); - // Add your custom toolchain - target to the command line - args.AddToolchain("clang_gnu", "Clang GNU toolchain", toolchain_clang_gnu); - args.AddTarget("clang_gnu", "Clang GNU target", target_clang_gnu); - - args.Parse(argc, argv); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) + .AddToolchain("clang_gnu", "Clang GNU toolchain", toolchain_clang_gnu) + .AddTarget("clang_gnu", "Clang GNU target", target_clang_gnu) + .Parse(argc, argv); // Additional boilerplate // Supplied at compile time Toolchain_gcc gcc; Toolchain_msvc msvc; - - ExecutableTarget_gcc g_foolib("foolib", gcc, ""); - ExecutableTarget_msvc m_foolib("foolib", msvc, ""); - - reg.Build(arg_gcc.state, foolib_build_cb, g_foolib); - reg.Build(arg_msvc.state, foolib_build_cb, m_foolib); - // Get custom toolchain from the command line, supplied at run time BaseToolchain clang = toolchain_clang_gnu.ConstructToolchain(); + ExecutableTarget_gcc g_foolib("foolib", gcc, ""); + ExecutableTarget_msvc m_foolib("foolib", msvc, ""); // Get compile_command and link_command from the command line - TargetConfig config; - config.compile_command = target_clang_gnu.compile_command; - config.link_command = target_clang_gnu.link_command; - Target_custom c_foolib("CFoolib.exe", TargetType::Executable, clang, "", config); - reg.Build(toolchain_clang_gnu.state, foolib_build_cb, c_foolib); + Target_custom c_foolib("CFoolib.exe", TargetType::Executable, clang, "", target_clang_gnu.GetTargetConfig()); + + Reg::Toolchain(arg_gcc.state) + .Build(foolib_build_cb, g_foolib); + Reg::Toolchain(arg_msvc.state) + .Build(foolib_build_cb, m_foolib); + Reg::Toolchain(toolchain_clang_gnu.state) + .Build( foolib_build_cb, c_foolib); // Build targets - reg.RunBuild(); + Reg::Run(); } static void foolib_build_cb(BaseTarget &target) { @@ -387,7 +379,6 @@ For super customized targets and toolchains .. code-block:: toml :linenos: - :emphasize-lines: 4,18 # See Multiple boilerplate .toml file @@ -418,7 +409,6 @@ Precompile header usage with GCC and MSVC compilers .. code-block:: cpp :linenos: - :emphasize-lines: 8,9,10,36,37,38 // Modified Lowlevel GCC Flags example for PCH @@ -487,7 +477,6 @@ Chain **Generators** and **Targets** using the ``Register`` module .. code-block:: cpp :linenos: - :emphasize-lines: 7,8,17,18 int main(int argc, char ** argv) { // See Multiple Boilerplate @@ -496,17 +485,19 @@ Chain **Generators** and **Targets** using the ``Register`` module Toolchain_msvc msvc; BaseGenerator cpp_generator("cpp_generator", ""); - reg.Build(cpp_generator_cb, cpp_generator); + Reg::Call().Build(cpp_generator_cb, cpp_generator); ExecutableTarget_gcc g_cpptarget("cpptarget", gcc, ""); - reg.Build(arg_gcc.state, cpp_target_cb, g_cpptarget, cpp_generator); + Reg::Toolchain(arg_gcc.state) + .Func([&](){ gcc.Verify(); }) + .Build(cpp_target_cb, g_cpptarget, cpp_generator) + .Dep(g_cpptarget, cpp_generator); ExecutableTarget_msvc m_cpptarget("cpptarget", msvc, ""); - reg.Build(arg_msvc.state, cpp_target_cb, m_cpptarget, cpp_generator); - - // cpp_generator runs before g_cpptarget and m_cpptarget - reg.Dep(g_cpptarget, cpp_generator); - reg.Dep(m_cpptarget, cpp_generator); + Reg::Toolchain(arg_msvc.state) + .Func([&](){ msvc.Verify(); }) + .Build(cpp_target_cb, m_cpptarget, cpp_generator) + .Dep(m_cpptarget, cpp_generator); } // Use a python generator to create main.cpp @@ -537,7 +528,6 @@ Target Info .. code-block:: cpp :linenos: - :emphasize-lines: 8,9 int main(int argc, char ** argv) { // See Multiple boilerplate @@ -546,14 +536,17 @@ Target Info Toolchain_msvc msvc; // TargetInfo - TargetInfo genericadd_ho("files"); - reg.Callback(genericadd_ho_cb, genericadd_ho); - + TargetInfo g_genericadd_ho(gcc, "files"); ExecutableTarget_gcc g_genericadd1("generic_add_1", gcc, "files"); - ExecutableTarget_msvc m_genericadd1("generic_add_1", msvc, "files"); + Reg::Toolchain(arg_gcc.state) + .Func(genericadd_ho_cb, g_genericadd_ho) + .Build(genericadd1_build_cb, g_genericadd1, g_genericadd_ho); - reg.Build(arg_gcc.state, genericadd1_build_cb, g_genericadd1, genericadd_ho); - reg.Build(arg_msvc.state, genericadd1_build_cb, m_genericadd1, genericadd_ho); + TargetInfo m_genericadd_ho(msvc, "files"); + ExecutableTarget_msvc m_genericadd1("generic_add_1", msvc, "files"); + Reg::Toolchain(arg_msvc.state) + .Func(genericadd_ho_cb, m_genericadd_ho) + .Build(genericadd1_build_cb, m_genericadd1, m_genericadd_ho); } // HO library contains include dirs and header files which are copied into executable target diff --git a/docs/source/getting_started/buildexe_package_manager.rst b/docs/source/getting_started/buildexe_package_manager.rst index 161e09ad..5e9493c8 100644 --- a/docs/source/getting_started/buildexe_package_manager.rst +++ b/docs/source/getting_started/buildexe_package_manager.rst @@ -192,7 +192,6 @@ Write your C++ "script" .. code-block:: cpp :linenos: - :emphasize-lines: 4,8,38,39,40,43,44,47,48,52,79 #include "buildcc.h" @@ -210,23 +209,22 @@ Write your C++ "script" static void hello_world_build_cb(BaseTarget &target, BaseTarget &fmt_lib); int main(int argc, char **argv) { - // 1. Get arguments - Args args; + // Get arguments ArgToolchain arg_gcc; - args.AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - args.Parse(argc, argv); - // 2. Initialize your environment - Register reg(args); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .Parse(argc, argv); - // 3. Pre-build steps - reg.Clean(clean_cb); + // Initialize your environment + Reg::Init(); - // 4. Build steps + // Pre-build steps + Reg::Call(Args::Clean().Func(clean_cb); + + // Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; - auto verified_toolchains = gcc.Verify(); - env::assert_fatal(!verified_toolchains.empty(), "GCC Toolchain not found"); // Setup your [Library]Target_[toolchain] fmtlib instance // Update your TargetEnv to point to `BuildExeLibDir::fmt` folder @@ -237,29 +235,24 @@ Write your C++ "script" // We use the build.fmt.h and build.fmt.cpp APIs to define how we build our fmtlib FmtConfig fmt_config; - reg.Build(arg_gcc.state, build_fmt_cb, fmt_lib, fmt_config); // Define our hello world executable ExecutableTarget_gcc hello_world("hello_world", gcc, ""); - reg.Build(arg_gcc.state, hello_world_build_cb, hello_world, fmt_lib); - + // Fmt lib is a dependency to the Hello world executable // This means that fmt lib is guaranteed to be built before the hello world executable - reg.Dep(hello_world, fmt_lib); - - // 5. Test steps i.e Hello world is automatically run - reg.Test(arg_gcc.state, "{executable}", hello_world); + Reg::Toolchain(arg_gcc.state) + .Build(arg_gcc.state, build_fmt_cb, fmt_lib, fmt_config) + .Build(hello_world_build_cb, hello_world, fmt_lib) + .Dep(hello_world, fmt_lib) + .Test("{executable}", hello_world);; + - // 6. Build Target + // Build and Test Target // Builds libfmt.a and ./hello_world - reg.RunBuild(); - - // 7. Test Target - // Executes ./hello_world - // Output -> Hello World - reg.RunTest(); + Reg::Run(); - // 8. Post Build steps + // Post Build steps // - Clang Compile Commands plugin::ClangCompileCommands({&hello_world}).Generate(); // - Graphviz dump diff --git a/docs/source/getting_started/buildexe_script_example.rst b/docs/source/getting_started/buildexe_script_example.rst index 23a3f211..ca229500 100644 --- a/docs/source/getting_started/buildexe_script_example.rst +++ b/docs/source/getting_started/buildexe_script_example.rst @@ -84,7 +84,6 @@ We then setup our main **toolchain**-**target** pairs. Highlighted below .. code-block:: cpp :linenos: - :emphasize-lines: 25,26,27,29,30 :caption: build.helloworld.cpp #include "buildcc.h" @@ -96,32 +95,33 @@ We then setup our main **toolchain**-**target** pairs. Highlighted below void hello_world_build_cb(BaseTarget & target); int main(int argc, char ** argv) { - // Step 1. Setup your args - Args args; + // Setup your args ArgToolchain arg_gcc; - args.AddToolchain("gcc", "GCC toolchain", arg_gcc); - args.Parse(argc, argv); - // Step 2. Register - Register reg(args); + Args::Init() + .AddToolchain("gcc", "GCC toolchain", arg_gcc) + .Parse(argc, argv); - // Step 3. Pre build steps + // Register + Reg::Init(); + + // Pre build steps // for example. clean your environment - reg.Clean(clean_cb); + Reg::Call(Args::Clean()).Func(clean_cb); - // Step 4. Build steps + // Build steps // Main setup Toolchain_gcc gcc; - auto verified_gcc_toolchains = gcc.Verify(); - env::assert_fatal(!verified_gcc_toolchains.empty(), "GCC toolchain not found"); - ExecutableTarget_gcc hello_world("hello_world", gcc, ""); - reg.Build(arg_gcc.state, hello_world_build_cb, hello_world); - // Step 5. Build your targets - reg.RunBuild(); + Reg::Toolchain(arg_gcc.state) + .Func([&](){ gcc.Verify() }) + .Build(hello_world_build_cb, hello_world); + + // Build your targets + Reg::Run(); - // Step 6. Post build steps + // Post build steps // for example. clang compile commands database plugin::ClangCompileCommands({&hello_world}).Generate(); diff --git a/docs/source/user_api/args.rst b/docs/source/user_api/args.rst index a0c8d482..e21db691 100644 --- a/docs/source/user_api/args.rst +++ b/docs/source/user_api/args.rst @@ -6,42 +6,55 @@ args.h .. doxygenclass:: buildcc::Args -.. doxygenclass:: buildcc::Args::Instance +.. doxygenstruct:: buildcc::ArgCustom .. doxygenstruct:: buildcc::ArgToolchainState .. doxygenstruct:: buildcc::ArgToolchain +.. doxygenstruct:: buildcc::ArgTarget + Example --------- .. code-block:: cpp :linenos: + using namespace buildcc; + + struct CustomData : ArgCustom { + void Add(CLI::App & app) override { + // setup your app from data1, data2, data3, data... + // NOTE: The Add method should not be invoked by the user + // NOTE: The Add method is only expected to be invoked once, not multiple times. + } + + std::string data1; + int data2; + float data3; + // etc + }; + int main(int argc, char ** argv) { - Args args; ArgToolchain arg_gcc_toolchain; - args.AddToolchain("gcc", "Generic GCC toolchain", arg_gcc_toolchain); - - // TODO, Add ArgTarget example (Currently incomplete) - args.Parse(argc, argv); + ArgCustomData custom_data; + Args::Init() + .AddToolchain("gcc", "Generic GCC toolchain", arg_gcc_toolchain) + .AddCustomCallback([](CLI::App &app) {}); + .AddCustomData(custom_data); + .Parse(argc, argv); // Root - args.GetProjectRootDir(); // Contains ``root_dir`` value - args.GetProjectBuildDir(); // Contains ``build_dir`` value - args.GetLogLevel(); // Contains ``loglevel`` enum - args.Clean(); // Contains ``clean`` value + Args::GetProjectRootDir(); // Contains ``root_dir`` value + Args::GetProjectBuildDir(); // Contains ``build_dir`` value + Args::GetLogLevel(); // Contains ``loglevel`` enum + Args::Clean(); // Contains ``clean`` value // Toolchain // .build, .test arg_gcc_toolchain.state; // .id, .name, .asm_compiler, .c_compiler, .cpp_compiler, .archiver, .linker -> BaseToolchain BaseToolchain gcc_toolchain = arg_gcc_toolchain.ConstructToolchain(); - - // Underlying CLI11 library - auto & app = args.Ref(); - const auto & app = args.ConstRef(); - return 0; } diff --git a/docs/source/user_api/register.rst b/docs/source/user_api/register.rst index 77033451..4d8d5795 100644 --- a/docs/source/user_api/register.rst +++ b/docs/source/user_api/register.rst @@ -4,9 +4,7 @@ Register register.h ----------- -.. doxygenclass:: buildcc::Register - :members: Register, Clean, Callback, CallbackIf, Build, Dep, Test, RunBuild, RunTest - +.. doxygenclass:: buildcc::Reg test_info.h ------------- @@ -26,19 +24,20 @@ Example static void callback_usage_func(const BigObj & cobj, BigObj & obj); int main(int argc, char ** argv) { - Args args; - args.Parse(argc, argv); + Args::Init() + .Parse(argc, argv); + + Reg::Init(); + Reg::Call(Args::Clean()).Func([](){ + fs::remove_all(Project::GetBuildDir()); + }) - Register reg(args); - reg.Clean([](){ - fs::remove_all(env::get_project_build_dir()); - }); BigObj obj; - reg.Callback(callback_usage_func, BigObj(), obj); + Reg::Call().Func(callback_usage_func, BigObj(), obj) bool expression = true; // false - reg.CallbackIf(expression, callback_usage_func, BigObj(), obj); + Reg::Call(expression).Func(callback_usage_func, BigObj(), obj) // Example snippets of these given in Target API // Build diff --git a/example/buildexe/libs/build.main.cpp b/example/buildexe/libs/build.main.cpp index c051e83b..64301e32 100644 --- a/example/buildexe/libs/build.main.cpp +++ b/example/buildexe/libs/build.main.cpp @@ -16,49 +16,42 @@ static void clean_cb(); static void hello_world_build_cb(BaseTarget &target, BaseTarget &fmt_lib); int main(int argc, char **argv) { - // 1. Get arguments - Args::Init(); + // Get arguments ArgToolchain arg_gcc; - Args::AddToolchain("gcc", "Generic gcc toolchain", arg_gcc); - Args::Parse(argc, argv); + Args::Init() + .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) + .Parse(argc, argv); - // 2. Initialize your environment - Register reg; + // Initialize your environment + Reg::Init(); - // 3. Pre-build steps - reg.Clean(clean_cb); + // Pre-build steps + Reg::Call(Args::Clean()).Func(clean_cb); - // 4. Build steps + // Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; - auto verified_toolchains = gcc.Verify(); - env::assert_fatal(!verified_toolchains.empty(), "GCC Toolchain not found"); StaticTarget_gcc fmt_lib( "libfmt", gcc, TargetEnv(BuildExeLibDir::fmt, Project::GetBuildDir() / "fmt")); FmtConfig fmt_config; - reg.Build(arg_gcc.state, build_fmt_cb, fmt_lib, fmt_config); - ExecutableTarget_gcc hello_world("hello_world", gcc, ""); - reg.Build(arg_gcc.state, hello_world_build_cb, hello_world, fmt_lib); - - reg.Dep(hello_world, fmt_lib); - - // 5. Test steps - reg.Test(arg_gcc.state, "{executable}", hello_world); - - // 6. Build Target - reg.RunBuild(); + Reg::Toolchain(arg_gcc.state) + .Func([&]() { gcc.Verify(); }) + .Build(build_fmt_cb, fmt_lib, fmt_config) + .Build(hello_world_build_cb, hello_world, fmt_lib) + .Dep(hello_world, fmt_lib) + .Test("{executable}", hello_world); - // 7. Test Target - reg.RunTest(); + // Build Target + Reg::Run(); - // 8. Post Build steps + // Post Build steps // - Clang Compile Commands plugin::ClangCompileCommands({&hello_world}).Generate(); // - Graphviz dump - std::cout << reg.GetTaskflow().dump() << std::endl; + std::cout << Reg::GetTaskflow().dump() << std::endl; return 0; } diff --git a/example/hybrid/custom_target/build.main.cpp b/example/hybrid/custom_target/build.main.cpp index 6b0829c0..c93b618c 100644 --- a/example/hybrid/custom_target/build.main.cpp +++ b/example/hybrid/custom_target/build.main.cpp @@ -8,49 +8,44 @@ static void foolib_build_cb(BaseTarget &target); static constexpr std::string_view EXE = "build"; int main(int argc, char **argv) { - // 1. Get arguments + // Get arguments ArgToolchain arg_gcc; ArgToolchain arg_msvc; - ArgToolchain toolchain_clang_gnu; - ArgTarget target_clang_gnu; + ArgToolchain arg_toolchain_clang_gnu; + ArgTarget arg_target_clang_gnu; Args::Init() .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) - .AddToolchain("clang_gnu", "Clang GNU toolchain", toolchain_clang_gnu) - .AddTarget("clang_gnu", "Clang GNU target", target_clang_gnu) + .AddToolchain("clang_gnu", "Clang GNU toolchain", arg_toolchain_clang_gnu) + .AddTarget("clang_gnu", "Clang GNU target", arg_target_clang_gnu) .Parse(argc, argv); - // 2. Initialize your environment - Register reg; + // Initialize your environment + Reg::Init(); - // 3. Pre-build steps - reg.Clean(clean_cb); + // Pre-build steps + Reg::Call(Args::Clean()).Func(clean_cb); - // 4. Build steps + // Build steps Toolchain_gcc gcc; - Toolchain_msvc msvc; - ExecutableTarget_gcc g_foolib("foolib", gcc, ""); - ExecutableTarget_msvc m_foolib("foolib", msvc, ""); + Reg::Toolchain(arg_gcc.state).Build(foolib_build_cb, g_foolib); - reg.Build(arg_gcc.state, foolib_build_cb, g_foolib); - reg.Build(arg_msvc.state, foolib_build_cb, m_foolib); + Toolchain_msvc msvc; + ExecutableTarget_msvc m_foolib("foolib", msvc, ""); + Reg::Toolchain(arg_msvc.state).Build(foolib_build_cb, m_foolib); // * NOTE, This is how we add our custom toolchain - BaseToolchain clang = toolchain_clang_gnu.ConstructToolchain(); - - // * M2, Get from Args (see build_linux.toml or build_win.toml files) - TargetConfig config; - config.compile_command = target_clang_gnu.compile_command; - config.link_command = target_clang_gnu.link_command; + BaseToolchain clang = arg_toolchain_clang_gnu.ConstructToolchain(); Target_custom c_foolib("CFoolib.exe", TargetType::Executable, clang, "", - config); - reg.Build(toolchain_clang_gnu.state, foolib_build_cb, c_foolib); + arg_target_clang_gnu.GetTargetConfig()); + Reg::Toolchain(arg_toolchain_clang_gnu.state) + .Build(foolib_build_cb, c_foolib); - // 5. - reg.RunBuild(); + // + Reg::Run(); - // 6. + // plugin::ClangCompileCommands({&g_foolib, &m_foolib, &c_foolib}).Generate(); return 0; diff --git a/example/hybrid/dep_chaining/build.cpp b/example/hybrid/dep_chaining/build.cpp index 49722ad4..3baddfe0 100644 --- a/example/hybrid/dep_chaining/build.cpp +++ b/example/hybrid/dep_chaining/build.cpp @@ -15,7 +15,7 @@ static void cpp_generator_cb(BaseGenerator &generator); static void c_generator_cb(BaseGenerator &generator); int main(int argc, char **argv) { - // 1. Get arguments + // Get arguments ArgToolchain arg_gcc; ArgToolchain arg_msvc; Args::Init() @@ -23,54 +23,45 @@ int main(int argc, char **argv) { .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) .Parse(argc, argv); - // 2. Initialize your environment - Register reg; + // Initialize your environment + Reg::Init(); - // 3. Pre-build steps - reg.Clean(clean_cb); + // Pre-build steps + Reg::Call(Args::Clean()).Func(clean_cb); - // 4. Build steps - // Explicit toolchain - target pairs - Toolchain_gcc gcc; - Toolchain_msvc msvc; - - // CPP + // Generator BaseGenerator cpp_generator("cpp_generator", ""); - reg.Build(cpp_generator_cb, cpp_generator); - - ExecutableTarget_gcc g_cpptarget("cpptarget", gcc, ""); - reg.Build(arg_gcc.state, cpp_target_cb, g_cpptarget, cpp_generator); - - ExecutableTarget_msvc m_cpptarget("cpptarget", msvc, ""); - reg.Build(arg_msvc.state, cpp_target_cb, m_cpptarget, cpp_generator); - - reg.Dep(g_cpptarget, cpp_generator); - reg.Dep(m_cpptarget, cpp_generator); - - // C BaseGenerator c_generator("c_generator", ""); - reg.Build(c_generator_cb, c_generator); + Reg::Call() + .Build(cpp_generator_cb, cpp_generator) + .Build(c_generator_cb, c_generator); + // Build steps + // Explicit toolchain - target pairs + Toolchain_gcc gcc; + ExecutableTarget_gcc g_cpptarget("cpptarget", gcc, ""); ExecutableTarget_gcc g_ctarget("ctarget", gcc, ""); - reg.Build(arg_gcc.state, c_target_cb, g_ctarget, c_generator); + Reg::Toolchain(arg_gcc.state) + .Build(cpp_target_cb, g_cpptarget, cpp_generator) + .Build(c_target_cb, g_ctarget, c_generator) + .Dep(g_cpptarget, cpp_generator) + .Dep(g_ctarget, c_generator) + .Test("{executable}", g_cpptarget) + .Test("{executable}", g_ctarget); + Toolchain_msvc msvc; + ExecutableTarget_msvc m_cpptarget("cpptarget", msvc, ""); ExecutableTarget_msvc m_ctarget("ctarget", msvc, ""); - reg.Build(arg_msvc.state, c_target_cb, m_ctarget, c_generator); - - reg.Dep(g_ctarget, c_generator); - reg.Dep(m_ctarget, c_generator); - - // Tests - reg.Test(arg_gcc.state, "{executable}", g_cpptarget); - reg.Test(arg_gcc.state, "{executable}", g_ctarget); - reg.Test(arg_msvc.state, "{executable}", m_cpptarget); - reg.Test(arg_msvc.state, "{executable}", m_ctarget); - - // 6. Build Target - reg.RunBuild(); + Reg::Toolchain(arg_msvc.state) + .Build(cpp_target_cb, m_cpptarget, cpp_generator) + .Build(c_target_cb, m_ctarget, c_generator) + .Dep(m_cpptarget, cpp_generator) + .Dep(m_ctarget, c_generator) + .Test("{executable}", m_cpptarget) + .Test("{executable}", m_ctarget); - // 7. Test Target - reg.RunTest(); + // Build and Test + Reg::Run(); // - Clang Compile Commands plugin::ClangCompileCommands( @@ -78,7 +69,7 @@ int main(int argc, char **argv) { .Generate(); // - Plugin Graph - std::string output = reg.GetTaskflow().dump(); + std::string output = Reg::GetTaskflow().dump(); const bool saved = env::save_file("graph.dot", output, false); env::assert_fatal(saved, "Could not save graph.dot file"); diff --git a/example/hybrid/external_lib/build.main.cpp b/example/hybrid/external_lib/build.main.cpp index b181281b..d74b63ef 100644 --- a/example/hybrid/external_lib/build.main.cpp +++ b/example/hybrid/external_lib/build.main.cpp @@ -19,23 +19,22 @@ int main(int argc, char **argv) { .Parse(argc, argv); // 2. Initialize your environment - Register reg; + Reg::Init(); // 3. Pre-build steps - reg.Clean(clean_cb); + Reg::Call(Args::Clean()).Func(clean_cb); // 4. Build steps Toolchain_gcc gcc; - Toolchain_msvc msvc; - ExecutableTarget_gcc g_foolib("cppflags", gcc, ""); - ExecutableTarget_msvc m_foolib("cppflags", msvc, ""); + Reg::Toolchain(arg_gcc.state).Build(foolib_build_cb, g_foolib); - reg.Build(arg_gcc.state, foolib_build_cb, g_foolib); - reg.Build(arg_msvc.state, foolib_build_cb, m_foolib); + Toolchain_msvc msvc; + ExecutableTarget_msvc m_foolib("cppflags", msvc, ""); + Reg::Toolchain(arg_msvc.state).Build(foolib_build_cb, m_foolib); // 5. - reg.RunBuild(); + Reg::Run(); // 6. plugin::ClangCompileCommands({&g_foolib, &m_foolib}).Generate(); diff --git a/example/hybrid/foolib/build.main.cpp b/example/hybrid/foolib/build.main.cpp index dc723d7b..aa005469 100644 --- a/example/hybrid/foolib/build.main.cpp +++ b/example/hybrid/foolib/build.main.cpp @@ -19,23 +19,22 @@ int main(int argc, char **argv) { .Parse(argc, argv); // 2. Initialize your environment - Register reg; + Reg::Init(); // 3. Pre-build steps - reg.Clean(clean_cb); + Reg::Call(Args::Clean()).Func(clean_cb); // 4. Build steps Toolchain_gcc gcc; - Toolchain_msvc msvc; - ExecutableTarget_gcc g_foolib("foolib", gcc, ""); - ExecutableTarget_msvc m_foolib("foolib", msvc, ""); + Reg::Toolchain(arg_gcc.state).Build(foolib_build_cb, g_foolib); - reg.Build(arg_gcc.state, foolib_build_cb, g_foolib); - reg.Build(arg_msvc.state, foolib_build_cb, m_foolib); + Toolchain_msvc msvc; + ExecutableTarget_msvc m_foolib("foolib", msvc, ""); + Reg::Toolchain(arg_msvc.state).Build(foolib_build_cb, m_foolib); // 5. - reg.RunBuild(); + Reg::Run(); // 6. plugin::ClangCompileCommands({&g_foolib, &m_foolib}).Generate(); diff --git a/example/hybrid/generic/build.cpp b/example/hybrid/generic/build.cpp index 3b9dcaa3..f5631b03 100644 --- a/example/hybrid/generic/build.cpp +++ b/example/hybrid/generic/build.cpp @@ -20,8 +20,11 @@ static void foolib_build_cb(BaseTarget &foolib_target); static void generic_build_cb(BaseTarget &generic_target, BaseTarget &foolib_target); +static void post_build_cb(BaseTarget &generic_target, + BaseTarget &foolib_target); + int main(int argc, char **argv) { - // 1. Get arguments + // Get arguments ArgToolchain custom_toolchain; TargetType default_lib_type{TargetType::StaticLibrary}; Args::Init() @@ -30,70 +33,33 @@ int main(int argc, char **argv) { [&](CLI::App &app) { args_lib_type_cb(app, default_lib_type); }) .Parse(argc, argv); - // 2. Initialize your environment - Register reg; + // Initialize your environment + Reg::Init(); - // 3. Pre-build steps - reg.Clean(clean_cb); + // Pre-build steps + Reg::Call(Args::Clean()).Func(clean_cb); - // 4. Build steps + // Build steps // Toolchain + Generic Target BaseToolchain toolchain = custom_toolchain.ConstructToolchain(); Target_generic foolib_target("libfoo", default_lib_type, toolchain, ""); - reg.Build(custom_toolchain.state, foolib_build_cb, foolib_target); - - // Target specific settings Target_generic generic_target("generic", TargetType::Executable, toolchain, "src"); - reg.Build(custom_toolchain.state, generic_build_cb, generic_target, - foolib_target); - reg.Dep(generic_target, foolib_target); - - // 5. Test steps - reg.Test(custom_toolchain.state, "{executable}", generic_target); - - // 6. Build Target - reg.RunBuild(); - - // 7. Post Build steps - // For Static Lib do nothing - // For Dynamic Lib we need to handle special cases - // - MSVC behaviour - // - Copy to executable location - if (default_lib_type == TargetType::DynamicLibrary) { - - // MSVC special case - fs::path copy_from_path; - fs::path copy_to_path; - if (toolchain.GetId() == ToolchainId::Msvc) { - copy_from_path = - fmt::format("{}.dll", path_as_string(foolib_target.GetTargetPath())); - copy_to_path = - generic_target.GetTargetBuildDir() / - fmt::format("{}.dll", - foolib_target.GetTargetPath().filename().string()); - } else { - copy_from_path = foolib_target.GetTargetPath(); - copy_to_path = - generic_target.GetTargetBuildDir() / - (foolib_target.GetName() + foolib_target.GetConfig().target_ext); - } - - // Copy case - if (generic_target.IsBuilt()) { - fs::remove(copy_to_path); - fs::copy(copy_from_path, copy_to_path); - } - } + Reg::Toolchain(custom_toolchain.state) + .Func([&]() { toolchain.Verify(); }) + .Build(foolib_build_cb, foolib_target) + .Build(generic_build_cb, generic_target, foolib_target) + .Dep(generic_target, foolib_target) + .Test("{executable}", generic_target); - // 8. Test Target - reg.RunTest(); + // Build Target + Reg::Run([&]() { post_build_cb(generic_target, foolib_target); }); // - Clang Compile Commands plugin::ClangCompileCommands({&foolib_target, &generic_target}).Generate(); // - Plugin Graph - std::string output = reg.GetTaskflow().dump(); + std::string output = Reg::GetTaskflow().dump(); const bool saved = env::save_file("graph.dot", output, false); env::assert_fatal(saved, "Could not save graph.dot file"); @@ -131,3 +97,35 @@ static void generic_build_cb(BaseTarget &generic_target, generic_target.AddSource("main.cpp"); generic_target.Build(); } + +void post_build_cb(BaseTarget &generic_target, BaseTarget &foolib_target) { + // For Static Lib do nothing + // For Dynamic Lib we need to handle special cases + // - MSVC behaviour + // - Copy to executable location + if (foolib_target.GetType() == TargetType::DynamicLibrary) { + // MSVC special case + fs::path copy_from_path; + fs::path copy_to_path; + if (foolib_target.GetToolchain().GetId() == ToolchainId::Msvc) { + copy_from_path = + fmt::format("{}.dll", path_as_string(foolib_target.GetTargetPath())); + copy_to_path = + generic_target.GetTargetBuildDir() / + fmt::format("{}.dll", + foolib_target.GetTargetPath().filename().string()); + } else { + copy_from_path = foolib_target.GetTargetPath(); + copy_to_path = + generic_target.GetTargetBuildDir() / + (foolib_target.GetName() + foolib_target.GetConfig().target_ext); + } + + // Copy case + // TODO, This should be baked into the `Target` API + if (generic_target.IsBuilt()) { + fs::remove(copy_to_path); + fs::copy(copy_from_path, copy_to_path); + } + } +} diff --git a/example/hybrid/pch/build.cpp b/example/hybrid/pch/build.cpp index a305367d..88bfc426 100644 --- a/example/hybrid/pch/build.cpp +++ b/example/hybrid/pch/build.cpp @@ -21,39 +21,33 @@ int main(int argc, char **argv) { .Parse(argc, argv); // 2. Initialize your environment - Register reg; + Reg::Init(); // 3. Pre-build steps - reg.Clean(clean_cb); + Reg::Call(Args::Clean()).Func(clean_cb); // 4. Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; - Toolchain_msvc msvc; - ExecutableTarget_gcc g_cppflags("cppflags", gcc, "files"); ExecutableTarget_gcc g_cflags("cflags", gcc, "files"); - ExecutableTarget_msvc m_cppflags("cppflags", msvc, "files"); - ExecutableTarget_msvc m_cflags("cflags", msvc, "files"); - // Select your builds and tests using the .toml files - reg.Build(arg_gcc.state, cppflags_build_cb, g_cppflags); - reg.Build(arg_msvc.state, cppflags_build_cb, m_cppflags); - reg.Build(arg_gcc.state, cflags_build_cb, g_cflags); - reg.Build(arg_msvc.state, cflags_build_cb, m_cflags); + Reg::Toolchain(arg_gcc.state) + .Build(cppflags_build_cb, g_cppflags) + .Build(cflags_build_cb, g_cflags) + .Test("{executable}", g_cppflags) + .Test("{executable}", g_cflags); - // 5. Test steps - // NOTE, For now they are just dummy callbacks - reg.Test(arg_gcc.state, "{executable}", g_cppflags); - reg.Test(arg_msvc.state, "{executable}", m_cppflags); - reg.Test(arg_gcc.state, "{executable}", g_cflags); - reg.Test(arg_msvc.state, "{executable}", m_cflags); - - // 6. Build Target - reg.RunBuild(); + Toolchain_msvc msvc; + ExecutableTarget_msvc m_cppflags("cppflags", msvc, "files"); + ExecutableTarget_msvc m_cflags("cflags", msvc, "files"); + Reg::Toolchain(arg_msvc.state) + .Build(cppflags_build_cb, m_cppflags) + .Build(cflags_build_cb, m_cflags) + .Test("{executable}", m_cppflags) + .Test("{executable}", m_cflags); - // 7. Test Target - reg.RunTest(); + Reg::Run(); // 8. Post Build steps @@ -61,7 +55,7 @@ int main(int argc, char **argv) { plugin::ClangCompileCommands({&g_cflags, &g_cppflags}).Generate(); // - Plugin Graph - std::string output = reg.GetTaskflow().dump(); + std::string output = Reg::GetTaskflow().dump(); const bool saved = env::save_file("graph.dot", output, false); env::assert_fatal(saved, "Could not save graph.dot file"); diff --git a/example/hybrid/simple/build.cpp b/example/hybrid/simple/build.cpp index 94c447f7..229f4f97 100644 --- a/example/hybrid/simple/build.cpp +++ b/example/hybrid/simple/build.cpp @@ -21,38 +21,34 @@ int main(int argc, char **argv) { .Parse(argc, argv); // 2. Initialize your environment - Register reg; + Reg::Init(); // 3. Pre-build steps - reg.Clean(clean_cb); + Reg::Call(Args::Clean()).Func(clean_cb); // 4. Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; - Toolchain_msvc msvc; - ExecutableTarget_gcc g_cppflags("cppflags", gcc, "files"); - ExecutableTarget_msvc m_cppflags("cppflags", msvc, "files"); ExecutableTarget_gcc g_cflags("cflags", gcc, "files"); - ExecutableTarget_msvc m_cflags("cflags", msvc, "files"); - - // Select your builds and tests using the .toml files - reg.Build(arg_gcc.state, cppflags_build_cb, g_cppflags); - reg.Build(arg_msvc.state, cppflags_build_cb, m_cppflags); - reg.Build(arg_gcc.state, cflags_build_cb, g_cflags); - reg.Build(arg_msvc.state, cflags_build_cb, m_cflags); + Reg::Toolchain(arg_gcc.state) + .Func([&]() { gcc.Verify(); }) + .Build(cppflags_build_cb, g_cppflags) + .Build(cflags_build_cb, g_cflags) + .Test("{executable}", g_cppflags) + .Test("{executable}", g_cflags); - // 5. Test steps - reg.Test(arg_gcc.state, "{executable}", g_cppflags); - reg.Test(arg_msvc.state, "{executable}", m_cppflags); - reg.Test(arg_gcc.state, "{executable}", g_cflags); - reg.Test(arg_msvc.state, "{executable}", m_cflags); - - // 6. Build Target - reg.RunBuild(); + Toolchain_msvc msvc; + ExecutableTarget_msvc m_cppflags("cppflags", msvc, "files"); + ExecutableTarget_msvc m_cflags("cflags", msvc, "files"); + Reg::Toolchain(arg_msvc.state) + .Func([&]() { msvc.Verify(); }) + .Build(cppflags_build_cb, m_cppflags) + .Build(cflags_build_cb, m_cflags) + .Test("{executable}", m_cppflags) + .Test("{executable}", m_cflags); - // 7. Test Target - reg.RunTest(); + Reg::Run(); // 8. Post Build steps @@ -61,7 +57,7 @@ int main(int argc, char **argv) { .Generate(); // - Plugin Graph - std::string output = reg.GetTaskflow().dump(); + std::string output = Reg::GetTaskflow().dump(); const bool saved = env::save_file("graph.dot", output, false); env::assert_fatal(saved, "Could not save graph.dot file"); diff --git a/example/hybrid/single/build.cpp b/example/hybrid/single/build.cpp index 491c8fc2..a6e59996 100644 --- a/example/hybrid/single/build.cpp +++ b/example/hybrid/single/build.cpp @@ -16,29 +16,24 @@ int main(int argc, char **argv) { .Parse(argc, argv); // 2. Initialize your environment - Register reg; + Reg::Init(); // 3. Pre-build steps - reg.Clean(clean_cb); + Reg::Call(Args::Clean()).Func(clean_cb); // 4. Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; - gcc.Verify(); - ExecutableTarget_gcc hello_world("hello_world", gcc, ""); // Select your builds and tests using the .toml files - reg.Build(arg_gcc.state, hello_world_build_cb, hello_world); - - // 5. Test steps - reg.Test(arg_gcc.state, "{executable}", hello_world); - - // 6. Build Target - reg.RunBuild(); + Reg::Toolchain(arg_gcc.state) + .Func([&]() { gcc.Verify(); }) + .Build(hello_world_build_cb, hello_world) + .Test("{executable}", hello_world); - // 7. Test Target - reg.RunTest(); + // 6. Build and Test Target + Reg::Run(); // 8. Post Build steps // - Clang Compile Commands diff --git a/example/hybrid/target_info/build.cpp b/example/hybrid/target_info/build.cpp index 600a8c71..e2684d0f 100644 --- a/example/hybrid/target_info/build.cpp +++ b/example/hybrid/target_info/build.cpp @@ -13,7 +13,7 @@ static void genericadd2_build_cb(BaseTarget &genericadd, const TargetInfo &genericadd_ho); int main(int argc, char **argv) { - // 1. Get arguments + // Get arguments ArgToolchain arg_gcc; ArgToolchain arg_msvc; Args::Init() @@ -21,61 +21,47 @@ int main(int argc, char **argv) { .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) .Parse(argc, argv); - // 2. Initialize your environment - Register reg; + // Initialize your environment + Reg::Init(); - // 3. Pre-build steps - reg.Clean(clean_cb); + // Pre-build steps + Reg::Call(Args::Clean()).Func(clean_cb); - // 4. Build steps + // Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; - Toolchain_msvc msvc; - - // TargetInfo TargetInfo gcc_genericadd_ho(gcc, "files"); - TargetInfo msvc_genericadd_ho(msvc, "files"); - reg.Callback(genericadd_ho_cb, gcc_genericadd_ho); - reg.Callback(genericadd_ho_cb, msvc_genericadd_ho); - ExecutableTarget_gcc g_genericadd1("generic_add_1", gcc, "files"); - ExecutableTarget_msvc m_genericadd1("generic_add_1", msvc, "files"); - ExecutableTarget_gcc g_genericadd2("generic_add_2", gcc, "files"); - ExecutableTarget_msvc m_genericadd2("generic_add_2", msvc, "files"); - - // Select your builds and tests using the .toml files - reg.Build(arg_gcc.state, genericadd1_build_cb, g_genericadd1, - gcc_genericadd_ho); - reg.Build(arg_gcc.state, genericadd2_build_cb, g_genericadd2, - gcc_genericadd_ho); - - reg.Build(arg_msvc.state, genericadd1_build_cb, m_genericadd1, - msvc_genericadd_ho); - reg.Build(arg_msvc.state, genericadd2_build_cb, m_genericadd2, - msvc_genericadd_ho); - - // 5. Test steps - // NOTE, For now they are just dummy callbacks - reg.Test(arg_gcc.state, "{executable}", g_genericadd1); - reg.Test(arg_msvc.state, "{executable}", m_genericadd1); - - reg.Test(arg_gcc.state, "{executable}", g_genericadd2); - reg.Test(arg_msvc.state, "{executable}", m_genericadd2); - - // 6. Build Target - reg.RunBuild(); - - // 7. Test Target - reg.RunTest(); - - // 8. Post Build steps + Reg::Toolchain(arg_gcc.state) + .Func([&]() { gcc.Verify(); }) + .Func(genericadd_ho_cb, gcc_genericadd_ho) + .Build(genericadd1_build_cb, g_genericadd1, gcc_genericadd_ho) + .Build(genericadd2_build_cb, g_genericadd2, gcc_genericadd_ho) + .Test("{executable}", g_genericadd1) + .Test("{executable}", g_genericadd2); + Toolchain_msvc msvc; + TargetInfo msvc_genericadd_ho(msvc, "files"); + ExecutableTarget_msvc m_genericadd1("generic_add_1", msvc, "files"); + ExecutableTarget_msvc m_genericadd2("generic_add_2", msvc, "files"); + Reg::Toolchain(arg_msvc.state) + .Func([&]() { msvc.Verify(); }) + .Func(genericadd_ho_cb, msvc_genericadd_ho) + .Build(genericadd1_build_cb, m_genericadd1, msvc_genericadd_ho) + .Build(genericadd2_build_cb, m_genericadd2, msvc_genericadd_ho) + .Test("{executable}", m_genericadd1) + .Test("{executable}", m_genericadd2); + + // Run + Reg::Run(); + + // Post Build steps // - Clang Compile Commands plugin::ClangCompileCommands({&g_genericadd1, &m_genericadd1}).Generate(); // - Plugin Graph - std::string output = reg.GetTaskflow().dump(); + std::string output = Reg::GetTaskflow().dump(); const bool saved = env::save_file("graph.dot", output, false); env::assert_fatal(saved, "Could not save graph.dot file"); From 69b09435fcaf1af802f8564e125931877b71d2bb Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 20 Apr 2022 22:56:58 -0700 Subject: [PATCH 13/35] Scoped Storage and static Storage class (#205) --- bootstrap/include/bootstrap/build_buildcc.h | 2 +- buildcc/buildcc.h | 2 +- buildcc/lib/args/CMakeLists.txt | 9 -- .../lib/args/test/test_persistent_storage.cpp | 60 ------------ buildcc/lib/env/CMakeLists.txt | 8 ++ .../include/env/storage.h} | 43 +++++++-- buildcc/lib/env/src/storage.cpp | 23 +++++ buildcc/lib/env/test/test_storage.cpp | 91 +++++++++++++++++++ buildexe/include/buildexe/build_env_setup.h | 2 +- 9 files changed, 162 insertions(+), 78 deletions(-) delete mode 100644 buildcc/lib/args/test/test_persistent_storage.cpp rename buildcc/lib/{args/include/args/persistent_storage.h => env/include/env/storage.h} (70%) create mode 100644 buildcc/lib/env/src/storage.cpp create mode 100644 buildcc/lib/env/test/test_storage.cpp diff --git a/bootstrap/include/bootstrap/build_buildcc.h b/bootstrap/include/bootstrap/build_buildcc.h index 7dcb9aee..4f0d59e7 100644 --- a/bootstrap/include/bootstrap/build_buildcc.h +++ b/bootstrap/include/bootstrap/build_buildcc.h @@ -77,7 +77,7 @@ class BuildBuildCC { const BaseToolchain &toolchain_; TargetEnv env_; - PersistentStorage storage_; + ScopedStorage storage_; }; } // namespace buildcc diff --git a/buildcc/buildcc.h b/buildcc/buildcc.h index 0959cea4..227d9ce0 100644 --- a/buildcc/buildcc.h +++ b/buildcc/buildcc.h @@ -27,6 +27,7 @@ #include "env/host_compiler.h" #include "env/util.h" #include "env/command.h" +#include "env/storage.h" // Base #include "toolchain/toolchain.h" @@ -57,6 +58,5 @@ // BuildCC Modules #include "args/args.h" #include "args/register.h" -#include "args/persistent_storage.h" #endif diff --git a/buildcc/lib/args/CMakeLists.txt b/buildcc/lib/args/CMakeLists.txt index 5b5843fa..6535b1f3 100644 --- a/buildcc/lib/args/CMakeLists.txt +++ b/buildcc/lib/args/CMakeLists.txt @@ -41,20 +41,12 @@ target_link_libraries(test_register PRIVATE mock_args ) -add_executable(test_persistent_storage - test/test_persistent_storage.cpp -) -target_link_libraries(test_persistent_storage PRIVATE mock_args) - add_test(NAME test_args COMMAND test_args WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test ) add_test(NAME test_register COMMAND test_register WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test ) -add_test(NAME test_persistent_storage COMMAND test_persistent_storage - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test -) endif() set(ARGS_SRCS @@ -64,7 +56,6 @@ set(ARGS_SRCS src/tasks.cpp include/args/args.h include/args/register.h - include/args/persistent_storage.h ) if(${BUILDCC_BUILD_AS_SINGLE_LIB}) diff --git a/buildcc/lib/args/test/test_persistent_storage.cpp b/buildcc/lib/args/test/test_persistent_storage.cpp deleted file mode 100644 index 56163d43..00000000 --- a/buildcc/lib/args/test/test_persistent_storage.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "args/persistent_storage.h" - -#include "target/generator.h" -#include "target/target.h" - -// NOTE, Make sure all these includes are AFTER the system and header includes -#include "CppUTest/CommandLineTestRunner.h" -#include "CppUTest/MemoryLeakDetectorNewMacros.h" -#include "CppUTest/TestHarness.h" -#include "CppUTest/Utest.h" -#include "CppUTestExt/MockSupport.h" - -// clang-format off -TEST_GROUP(PersistentStorageTestGroup) -{ -}; -// clang-format on - -static buildcc::BaseToolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); - -TEST(PersistentStorageTestGroup, BasicUsage) { - buildcc::PersistentStorage persistent; - persistent.Add("target_identifier", "target_name", - buildcc::TargetType::Executable, gcc, ""); - persistent.Add("generator_identifier", - "generator_name", ""); - - // Usage - persistent.ConstRef("target_identifier").GetName(); - persistent.Ref("generator_identifier").GetTaskflow(); - - // Automatic cleanup here -} - -TEST(PersistentStorageTestGroup, IncorrectUsage) { - buildcc::PersistentStorage persistent; - persistent.Add("target_identifier", "target_name", - buildcc::TargetType::Executable, gcc, ""); - - // We try to cast to a different type! - CHECK_THROWS(std::exception, - persistent.Ref("target_identifier")); - - // We use a wrong identifier - CHECK_THROWS(std::exception, - persistent.Ref("generator_identifier")); -} - -std::string &toReference(std::string *pointer) { return *pointer; } - -TEST(PersistentStorageTestGroup, NullptrDelete) { - buildcc::PersistentStorage persistent; - persistent.Remove(nullptr); -} - -int main(int ac, char **av) { - buildcc::Project::Init(fs::current_path(), fs::current_path()); - return CommandLineTestRunner::RunAllTests(ac, av); -} diff --git a/buildcc/lib/env/CMakeLists.txt b/buildcc/lib/env/CMakeLists.txt index f76bcc34..f18d6b24 100644 --- a/buildcc/lib/env/CMakeLists.txt +++ b/buildcc/lib/env/CMakeLists.txt @@ -6,6 +6,7 @@ if (${TESTING}) src/env.cpp src/task_state.cpp + src/storage.cpp src/command.cpp mock/execute.cpp @@ -38,10 +39,14 @@ if (${TESTING}) add_executable(test_command test/test_command.cpp) target_link_libraries(test_command PRIVATE mock_env) + add_executable(test_storage test/test_storage.cpp) + target_link_libraries(test_storage PRIVATE mock_env) + add_test(NAME test_static_project COMMAND test_static_project) add_test(NAME test_env_util COMMAND test_env_util) add_test(NAME test_task_state COMMAND test_task_state) add_test(NAME test_command COMMAND test_command) + add_test(NAME test_storage COMMAND test_storage) endif() set(ENV_SRCS @@ -64,6 +69,9 @@ set(ENV_SRCS src/command.cpp src/execute.cpp include/env/command.h + + src/storage.cpp + include/env/storage.h ) if(${BUILDCC_BUILD_AS_SINGLE_LIB}) diff --git a/buildcc/lib/args/include/args/persistent_storage.h b/buildcc/lib/env/include/env/storage.h similarity index 70% rename from buildcc/lib/args/include/args/persistent_storage.h rename to buildcc/lib/env/include/env/storage.h index 573c0172..ccd1d1c9 100644 --- a/buildcc/lib/args/include/args/persistent_storage.h +++ b/buildcc/lib/env/include/env/storage.h @@ -14,10 +14,11 @@ * limitations under the License. */ -#ifndef ARGS_PERSISTENT_STORAGE_H_ -#define ARGS_PERSISTENT_STORAGE_H_ +#ifndef ENV_STORAGE_H_ +#define ENV_STORAGE_H_ #include +#include #include #include #include @@ -28,10 +29,10 @@ namespace buildcc { -class PersistentStorage { +class ScopedStorage { public: - PersistentStorage() {} - ~PersistentStorage() { + ScopedStorage() {} + ~ScopedStorage() { for (const auto &ptr_iter : ptrs_) { ptr_iter.second.destructor(); } @@ -39,6 +40,8 @@ class PersistentStorage { env::assert_fatal(ptrs_.empty(), "Memory not deallocated"); } + ScopedStorage(const ScopedStorage &) = delete; + template T &Add(const std::string &identifier, Params &&...params) { T *ptr = new T(std::forward(params)...); @@ -69,7 +72,7 @@ class PersistentStorage { // https://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func/123995 template T &Ref(const std::string &identifier) { return const_cast( - static_cast(*this).ConstRef(identifier)); + static_cast(*this).ConstRef(identifier)); } private: @@ -90,6 +93,34 @@ class PersistentStorage { std::unordered_map ptrs_; }; +class Storage { +public: + Storage() = delete; + Storage(const Storage &) = delete; + Storage(Storage &&) = delete; + + static void Init() { internal_ = std::make_unique(); } + static void Deinit() { internal_.reset(nullptr); } + + template + static T &Add(const std::string &identifier, Params &&...params) { + return internal_->Add(identifier, + std::forward(params)...); + } + + template + static const T &ConstRef(const std::string &identifier) { + return internal_->ConstRef(identifier); + } + + template static T &Ref(const std::string &identifier) { + return internal_->Ref(identifier); + } + +private: + static std::unique_ptr internal_; +}; + } // namespace buildcc #endif diff --git a/buildcc/lib/env/src/storage.cpp b/buildcc/lib/env/src/storage.cpp new file mode 100644 index 00000000..37bae38b --- /dev/null +++ b/buildcc/lib/env/src/storage.cpp @@ -0,0 +1,23 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "env/storage.h" + +namespace buildcc { + +std::unique_ptr Storage::internal_; + +} diff --git a/buildcc/lib/env/test/test_storage.cpp b/buildcc/lib/env/test/test_storage.cpp new file mode 100644 index 00000000..ccd4be83 --- /dev/null +++ b/buildcc/lib/env/test/test_storage.cpp @@ -0,0 +1,91 @@ +#include "env/storage.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(ScopedStorageTestGroup) +{ +}; + +TEST_GROUP(StorageTestGroup) +{ + void setup() { + buildcc::Storage::Init(); + } + void teardown() { + buildcc::Storage::Deinit(); + } +}; +// clang-format on + +class BigObj {}; + +class BigObjWithParameters { +public: + BigObjWithParameters(const std::string &name, int id, const BigObj &obj) + : name_(name) { + (void)id; + (void)obj; + } + + const std::string &GetName() const { return name_; } + +private: + std::string name_; +}; + +static BigObj obj; + +TEST(ScopedStorageTestGroup, BasicUsage) { + buildcc::ScopedStorage storage; + storage.Add("identifier", "name", 10, obj); + storage.Add("identifier2", "name2", 12, obj); + + // Usage + storage.ConstRef("identifier").GetName(); + storage.Ref("identifier2").GetName(); + + // Automatic cleanup here +} + +TEST(ScopedStorageTestGroup, IncorrectUsage) { + buildcc::ScopedStorage storage; + storage.Add("identifier", "name", 10, obj); + + // We try to cast to a different type! + CHECK_THROWS(std::exception, storage.Ref("identifier")); + + // We use a wrong identifier + CHECK_THROWS(std::exception, + storage.Ref("identifier2")); +} + +std::string &toReference(std::string *pointer) { return *pointer; } + +TEST(ScopedStorageTestGroup, NullptrDelete) { + buildcc::ScopedStorage storage; + storage.Remove(nullptr); +} + +TEST(StorageTestGroup, BasicUsage) { + buildcc::Storage::Add("identifier", "name", 10, obj); + buildcc::Storage::Add("identifier2", "name2", 12, obj); + + // Usage + const auto &bigobj = + buildcc::Storage::ConstRef("identifier").GetName(); + const auto &bigobj2 = + buildcc::Storage::Ref("identifier2").GetName(); + + STRCMP_EQUAL(bigobj.c_str(), "name"); + STRCMP_EQUAL(bigobj2.c_str(), "name2"); +} + +int main(int ac, char **av) { + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildexe/include/buildexe/build_env_setup.h b/buildexe/include/buildexe/build_env_setup.h index e36983d4..f76fd9fc 100644 --- a/buildexe/include/buildexe/build_env_setup.h +++ b/buildexe/include/buildexe/build_env_setup.h @@ -66,7 +66,7 @@ class BuildEnvSetup { const BuildExeArgs &buildexe_args_; ArgToolchainState state_; - PersistentStorage storage_; + ScopedStorage storage_; }; } // namespace buildcc From e41bf009ca7d67dbda9fd39dde62c80e5af1b185 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Fri, 22 Apr 2022 01:51:51 -0700 Subject: [PATCH 14/35] Assert Fatal thread behavior (#206) --- buildcc/lib/env/CMakeLists.txt | 5 +- buildcc/lib/env/include/env/assert_fatal.h | 6 +- buildcc/lib/env/include/env/assert_throw.h | 69 ------------------ buildcc/lib/env/include/env/storage.h | 10 +-- buildcc/lib/env/src/assert_fatal.cpp | 23 +++++- buildcc/lib/env/src/storage.cpp | 6 ++ buildcc/lib/env/test/test_assert_fatal.cpp | 72 +++++++++++++++++++ buildcc/lib/env/test/test_storage.cpp | 8 +++ buildcc/lib/target/src/generator/task.cpp | 4 +- .../target/src/target/friend/compile_pch.cpp | 6 +- .../target/src/target/friend/link_target.cpp | 2 +- buildcc/lib/target/src/target/tasks.cpp | 4 +- buildcc/schema/include/schema/path.h | 4 +- 13 files changed, 133 insertions(+), 86 deletions(-) delete mode 100644 buildcc/lib/env/include/env/assert_throw.h create mode 100644 buildcc/lib/env/test/test_assert_fatal.cpp diff --git a/buildcc/lib/env/CMakeLists.txt b/buildcc/lib/env/CMakeLists.txt index f18d6b24..8af914c2 100644 --- a/buildcc/lib/env/CMakeLists.txt +++ b/buildcc/lib/env/CMakeLists.txt @@ -42,11 +42,15 @@ if (${TESTING}) add_executable(test_storage test/test_storage.cpp) target_link_libraries(test_storage PRIVATE mock_env) + add_executable(test_assert_fatal test/test_assert_fatal.cpp) + target_link_libraries(test_assert_fatal PRIVATE mock_env) + add_test(NAME test_static_project COMMAND test_static_project) add_test(NAME test_env_util COMMAND test_env_util) add_test(NAME test_task_state COMMAND test_task_state) add_test(NAME test_command COMMAND test_command) add_test(NAME test_storage COMMAND test_storage) + add_test(NAME test_assert_fatal COMMAND test_assert_fatal) endif() set(ENV_SRCS @@ -54,7 +58,6 @@ set(ENV_SRCS src/assert_fatal.cpp src/logging.cpp include/env/assert_fatal.h - include/env/assert_throw.h include/env/env.h include/env/logging.h include/env/util.h diff --git a/buildcc/lib/env/include/env/assert_fatal.h b/buildcc/lib/env/include/env/assert_fatal.h index 481e7a3c..9f048066 100644 --- a/buildcc/lib/env/include/env/assert_fatal.h +++ b/buildcc/lib/env/include/env/assert_fatal.h @@ -24,7 +24,11 @@ namespace buildcc::env { /** - * @brief During Release -> std::terminate + * @brief During Release -> + * NOT THREADED : std::exit + * THREADED : throw std::exception (it is wrong to exit + * when in a threaded state. We want to handle the exception and gracefully + * exit) * During Unit Test -> throw std::exception */ [[noreturn]] void assert_handle_fatal(); diff --git a/buildcc/lib/env/include/env/assert_throw.h b/buildcc/lib/env/include/env/assert_throw.h deleted file mode 100644 index b070f22e..00000000 --- a/buildcc/lib/env/include/env/assert_throw.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ENV_ASSERT_THROW_H_ -#define ENV_ASSERT_THROW_H_ - -#include - -#include "logging.h" - -namespace buildcc::env { - -/** - * @brief Compile time expr asserts fatally when false - */ -template -inline void assert_throw([[maybe_unused]] const char *message) { - if constexpr (!expr) { - env::log_critical("assert", message); - // TODO, If needed specialize this - throw std::exception(); - } -} - -/** - * @brief Compile time expr asserts fatally when false - */ -template inline void assert_throw(const std::string &message) { - assert_throw(message.c_str()); -} - -/** - * @brief Runtime expr asserts fatally when false - */ -inline void assert_throw(bool expression, const char *message) { - if (!expression) { - assert_throw(message); - } -} - -/** - * @brief Runtime expr asserts fatally when false - */ -inline void assert_throw(bool expression, const std::string &message) { - assert_throw(expression, message.c_str()); -} - -} // namespace buildcc::env - -/** - * @brief Runtime expr assert throws when false - */ -#define ASSERT_THROW(expr, message) \ - ((expr) ? static_cast(0) : buildcc::env::assert_throw(message)) - -#endif diff --git a/buildcc/lib/env/include/env/storage.h b/buildcc/lib/env/include/env/storage.h index ccd1d1c9..6ca3908b 100644 --- a/buildcc/lib/env/include/env/storage.h +++ b/buildcc/lib/env/include/env/storage.h @@ -104,19 +104,21 @@ class Storage { template static T &Add(const std::string &identifier, Params &&...params) { - return internal_->Add(identifier, - std::forward(params)...); + return Ref().Add(identifier, std::forward(params)...); } template static const T &ConstRef(const std::string &identifier) { - return internal_->ConstRef(identifier); + return Ref().ConstRef(identifier); } template static T &Ref(const std::string &identifier) { - return internal_->Ref(identifier); + return Ref().Ref(identifier); } +private: + static ScopedStorage &Ref(); + private: static std::unique_ptr internal_; }; diff --git a/buildcc/lib/env/src/assert_fatal.cpp b/buildcc/lib/env/src/assert_fatal.cpp index 7d7becf3..c1f6dd62 100644 --- a/buildcc/lib/env/src/assert_fatal.cpp +++ b/buildcc/lib/env/src/assert_fatal.cpp @@ -17,9 +17,30 @@ #include "env/assert_fatal.h" #include +#include + +namespace { + +std::thread::id main_id = std::this_thread::get_id(); + +bool IsRunningOnThread() { + bool threaded = true; + if (std::this_thread::get_id() == main_id) { + threaded = false; + } + return threaded; +} + +} // namespace namespace buildcc::env { -[[noreturn]] void assert_handle_fatal() { std::terminate(); } +[[noreturn]] void assert_handle_fatal() { + if (!IsRunningOnThread()) { + std::exit(1); + } else { + throw std::exception(); + } +} } // namespace buildcc::env diff --git a/buildcc/lib/env/src/storage.cpp b/buildcc/lib/env/src/storage.cpp index 37bae38b..6712c008 100644 --- a/buildcc/lib/env/src/storage.cpp +++ b/buildcc/lib/env/src/storage.cpp @@ -20,4 +20,10 @@ namespace buildcc { std::unique_ptr Storage::internal_; +ScopedStorage &Storage::Ref() { + env::assert_fatal(internal_ != nullptr, + "Initialize Storage using the Storage::Init API"); + return *internal_; } + +} // namespace buildcc diff --git a/buildcc/lib/env/test/test_assert_fatal.cpp b/buildcc/lib/env/test/test_assert_fatal.cpp new file mode 100644 index 00000000..67e3b986 --- /dev/null +++ b/buildcc/lib/env/test/test_assert_fatal.cpp @@ -0,0 +1,72 @@ +#include + +#include "taskflow/taskflow.hpp" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +namespace { + +std::thread::id my_main_thread = std::this_thread::get_id(); + +bool IsRunningInThread() { + bool threaded = true; + if (std::this_thread::get_id() == my_main_thread) { + threaded = false; + } + return threaded; +} + +void assert_handle_fatal() { + if (IsRunningInThread()) { + mock().actualCall("assert_handle_fatal_threaded"); + } else { + mock().actualCall("assert_handle_fatal_main"); + } +} + +} // namespace + +// clang-format off +TEST_GROUP(AssertFatalTestGroup) +{ + void teardown() { + mock().clear(); + } +}; +// clang-format on + +TEST(AssertFatalTestGroup, AssertFatal_IsThreadedCheck) { + CHECK_FALSE(IsRunningInThread()); + + tf::Taskflow tf; + tf.emplace([]() { CHECK_TRUE(IsRunningInThread()); }); + + tf::Executor ex(1); + ex.run(tf); + ex.wait_for_all(); +} + +TEST(AssertFatalTestGroup, AssertFatal_Threaded) { + mock().expectOneCall("assert_handle_fatal_threaded"); + + tf::Taskflow tf; + tf.emplace([]() { assert_handle_fatal(); }); + + tf::Executor ex(1); + ex.run(tf); + ex.wait_for_all(); +} + +TEST(AssertFatalTestGroup, AssertFatal_NotThreaded) { + mock().expectOneCall("assert_handle_fatal_main"); + assert_handle_fatal(); +} + +int main(int ac, char **av) { + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/lib/env/test/test_storage.cpp b/buildcc/lib/env/test/test_storage.cpp index ccd4be83..929fc0ba 100644 --- a/buildcc/lib/env/test/test_storage.cpp +++ b/buildcc/lib/env/test/test_storage.cpp @@ -86,6 +86,14 @@ TEST(StorageTestGroup, BasicUsage) { STRCMP_EQUAL(bigobj2.c_str(), "name2"); } +TEST(StorageTestGroup, UsageWithoutInit) { + buildcc::Storage::Deinit(); + + CHECK_THROWS(std::exception, buildcc::Storage::Add("integer")); + CHECK_THROWS(std::exception, buildcc::Storage::Ref("integer")); + CHECK_THROWS(std::exception, buildcc::Storage::ConstRef("integer")); +} + int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/src/generator/task.cpp b/buildcc/lib/target/src/generator/task.cpp index 60e396fe..673e612e 100644 --- a/buildcc/lib/target/src/generator/task.cpp +++ b/buildcc/lib/target/src/generator/task.cpp @@ -52,7 +52,7 @@ void Generator::GenerateTask() { auto run_command = [this](const std::string &command) { try { bool success = env::Command::Execute(command); - env::assert_throw(success, fmt::format("{} failed", command)); + env::assert_fatal(success, fmt::format("{} failed", command)); } catch (...) { std::lock_guard guard(task_state_mutex_); task_state_ = env::TaskState::FAILURE; @@ -104,7 +104,7 @@ void Generator::GenerateTask() { if (dirty_) { try { serialization_.UpdateStore(user_); - env::assert_throw(serialization_.StoreToFile(), + env::assert_fatal(serialization_.StoreToFile(), fmt::format("Store failed for {}", name_)); } catch (...) { task_state_ = env::TaskState::FAILURE; diff --git a/buildcc/lib/target/src/target/friend/compile_pch.cpp b/buildcc/lib/target/src/target/friend/compile_pch.cpp index 83e7cf62..8af27578 100644 --- a/buildcc/lib/target/src/target/friend/compile_pch.cpp +++ b/buildcc/lib/target/src/target/friend/compile_pch.cpp @@ -54,7 +54,7 @@ void AggregateToFile(const fs::path &filename, }); bool success = buildcc::env::save_file( buildcc::path_as_string(filename).c_str(), constructed_output, false); - buildcc::env::assert_throw(success, "Could not save pch file"); + buildcc::env::assert_fatal(success, "Could not save pch file"); } } // namespace @@ -108,10 +108,10 @@ void CompilePch::BuildCompile() { const std::string p = fmt::format("{}", source_path_); const bool save = env::save_file(p.c_str(), {"//Generated by BuildCC"}, false); - env::assert_throw(save, fmt::format("Could not save {}", p)); + env::assert_fatal(save, fmt::format("Could not save {}", p)); } bool success = env::Command::Execute(command_); - env::assert_throw(success, "Failed to compile pch"); + env::assert_fatal(success, "Failed to compile pch"); } } diff --git a/buildcc/lib/target/src/target/friend/link_target.cpp b/buildcc/lib/target/src/target/friend/link_target.cpp index 49bc52b7..8e1f4b8b 100644 --- a/buildcc/lib/target/src/target/friend/link_target.cpp +++ b/buildcc/lib/target/src/target/friend/link_target.cpp @@ -98,7 +98,7 @@ void LinkTarget::BuildLink() { if (target_.dirty_) { bool success = env::Command::Execute(command_); - env::assert_throw(success, "Failed to link target"); + env::assert_fatal(success, "Failed to link target"); target_.serialization_.UpdateTargetCompiled(); } } diff --git a/buildcc/lib/target/src/target/tasks.cpp b/buildcc/lib/target/src/target/tasks.cpp index 7b659787..7f46c99f 100644 --- a/buildcc/lib/target/src/target/tasks.cpp +++ b/buildcc/lib/target/src/target/tasks.cpp @@ -124,7 +124,7 @@ void CompileObject::Task() { try { bool success = env::Command::Execute( GetObjectData(s.GetPathname()).command); - env::assert_throw(success, "Could not compile source"); + env::assert_fatal(success, "Could not compile source"); target_.serialization_.AddSource(s); } catch (...) { target_.SetTaskStateFailure(); @@ -170,7 +170,7 @@ void Target::EndTask() { if (dirty_) { try { serialization_.UpdateStore(user_); - env::assert_throw(serialization_.StoreToFile(), + env::assert_fatal(serialization_.StoreToFile(), fmt::format("Store failed for {}", GetName())); state_.BuildCompleted(); } catch (...) { diff --git a/buildcc/schema/include/schema/path.h b/buildcc/schema/include/schema/path.h index 2ee2f3ae..1810d3d1 100644 --- a/buildcc/schema/include/schema/path.h +++ b/buildcc/schema/include/schema/path.h @@ -25,7 +25,7 @@ #include // Env -#include "env/assert_throw.h" +#include "env/assert_fatal.h" // Third party #include "fmt/format.h" @@ -51,7 +51,7 @@ class Path { std::filesystem::last_write_time(pathname, errcode) .time_since_epoch() .count(); - env::assert_throw(errcode.value() == 0, + env::assert_fatal(errcode.value() == 0, fmt::format("{} not found", pathname)); return Path(pathname, last_write_timestamp); From d22c750a26bbf9ea7f36312bf34afeecaf6c42c4 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 24 Apr 2022 02:56:12 -0700 Subject: [PATCH 15/35] Updated examples (#207) --- bootstrap/include/bootstrap/build_buildcc.h | 22 +++++++++++- bootstrap/main.buildcc.cpp | 6 ++-- bootstrap/src/build_buildcc.cpp | 31 +++++++++++------ buildcc/lib/args/include/args/args.h | 7 ++-- buildcc/lib/args/include/args/register.h | 3 ++ buildcc/lib/env/include/env/storage.h | 2 ++ buildexe/buildexe.cpp | 3 +- buildexe/include/buildexe/build_env_setup.h | 6 ++-- buildexe/src/build_env_setup.cpp | 4 +-- docs/source/arch/cmake_boilerplate.rst | 1 - docs/source/user_api/environment.rst | 13 ------- example/hybrid/external_lib/build.main.cpp | 38 +++++++++++++-------- example/hybrid/foolib/build.foo.cpp | 6 ++-- example/hybrid/foolib/build.foo.h | 2 +- example/hybrid/foolib/build.main.cpp | 38 +++++++++++++-------- example/hybrid/generic/build.cpp | 14 ++++---- example/hybrid/pch/build.cpp | 10 +++--- example/hybrid/simple/build.cpp | 10 +++--- example/hybrid/single/build.cpp | 12 +++---- 19 files changed, 135 insertions(+), 93 deletions(-) diff --git a/bootstrap/include/bootstrap/build_buildcc.h b/bootstrap/include/bootstrap/build_buildcc.h index 4f0d59e7..ccfe2602 100644 --- a/bootstrap/include/bootstrap/build_buildcc.h +++ b/bootstrap/include/bootstrap/build_buildcc.h @@ -60,7 +60,9 @@ class BuildBuildCC { public: BuildBuildCC(const BaseToolchain &toolchain, const TargetEnv &env) - : toolchain_(toolchain), env_(env) {} + : toolchain_(toolchain), env_(env) { + Initialize(); + } BuildBuildCC(const BuildBuildCC &) = delete; void Setup(const ArgToolchainState &state); @@ -73,6 +75,24 @@ class BuildBuildCC { return storage_.Ref(kBuildccLibName); } +private: + void Initialize(); + ExecutableTarget_generic &GetFlatc() { + return storage_.Ref(kFlatcExeName); + } + BaseGenerator &GetSchemaGen() { + return storage_.Ref(kSchemaGenName); + } + TargetInfo &GetFlatbuffersHo() { + return storage_.Ref(kFlatbuffersHoName); + } + TargetInfo &GetCli11Ho() { return storage_.Ref(kCli11HoName); } + TargetInfo &GetFmtHo() { return storage_.Ref(kFmtHoName); } + TargetInfo &GetSpdlogHo() { return storage_.Ref(kSpdlogHoName); } + TargetInfo &GetTaskflowHo() { + return storage_.Ref(kTaskflowHoName); + } + private: const BaseToolchain &toolchain_; TargetEnv env_; diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index 9115346e..a1109bf1 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -42,16 +42,16 @@ int main(int argc, char **argv) { Reg::Call(Args::Clean()).Func(clean_cb); BaseToolchain toolchain = custom_toolchain_arg.ConstructToolchain(); - toolchain.Verify(); BuildBuildCC buildcc( toolchain, TargetEnv(Project::GetRootDir(), Project::GetBuildDir())); - buildcc.Setup(custom_toolchain_arg.state); + auto &buildcc_lib = buildcc.GetBuildcc(); - const auto &buildcc_lib = buildcc.GetBuildcc(); ExecutableTarget_generic buildcc_hybrid_simple_example( "buildcc_hybrid_simple_example", toolchain, "example/hybrid/simple"); Reg::Toolchain(custom_toolchain_arg.state) + .Func([&]() { toolchain.Verify(); }) + .BuildPackage(buildcc) .Build(hybrid_simple_example_cb, buildcc_hybrid_simple_example, buildcc_lib) .Dep(buildcc_hybrid_simple_example, buildcc_lib); diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index d5b111b6..4245a6cd 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -189,44 +189,44 @@ static void global_flags_cb(TargetInfo &global_info, } } -void BuildBuildCC::Setup(const ArgToolchainState &state) { - auto &flatc_exe = storage_.Add( +void BuildBuildCC::Initialize() { + (void)storage_.Add( kFlatcExeName, kFlatcExeName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "flatbuffers", env_.GetTargetBuildDir())); // Schema - auto &schema_gen = storage_.Add( + (void)storage_.Add( kSchemaGenName, kSchemaGenName, TargetEnv(env_.GetTargetRootDir() / "buildcc" / "schema", env_.GetTargetBuildDir() / toolchain_.GetName())); // Flatbuffers HO lib - auto &flatbuffers_ho_lib = storage_.Add( + (void)storage_.Add( kFlatbuffersHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "flatbuffers", env_.GetTargetBuildDir())); // CLI11 HO lib - auto &cli11_ho_lib = storage_.Add( + (void)storage_.Add( kCli11HoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "CLI11", env_.GetTargetBuildDir())); // fmt HO lib - auto &fmt_ho_lib = storage_.Add( + (void)storage_.Add( kFmtHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "fmt", env_.GetTargetBuildDir())); // spdlog HO lib - auto &spdlog_ho_lib = storage_.Add( + (void)storage_.Add( kSpdlogHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "spdlog", env_.GetTargetBuildDir())); // taskflow HO lib - auto &taskflow_ho_lib = storage_.Add( + (void)storage_.Add( kTaskflowHoName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "taskflow", env_.GetTargetBuildDir())); @@ -234,7 +234,7 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { // Tiny-process-library lib // TODO, Make this a generic selection between StaticTarget and // DynamicTarget - auto &tpl_lib = storage_.Add( + (void)storage_.Add( kTplLibName, kTplLibName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "third_party" / "tiny-process-library", @@ -243,10 +243,21 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { // BuildCC lib // TODO, Make this a generic selection between StaticTarget and // DynamicTarget - auto &buildcc_lib = storage_.Add( + (void)storage_.Add( kBuildccLibName, kBuildccLibName, toolchain_, TargetEnv(env_.GetTargetRootDir() / "buildcc", env_.GetTargetBuildDir())); +} +void BuildBuildCC::Setup(const ArgToolchainState &state) { + auto &flatc_exe = GetFlatc(); + auto &schema_gen = GetSchemaGen(); + auto &flatbuffers_ho_lib = GetFlatbuffersHo(); + auto &cli11_ho_lib = GetCli11Ho(); + auto &fmt_ho_lib = GetFmtHo(); + auto &spdlog_ho_lib = GetSpdlogHo(); + auto &taskflow_ho_lib = GetTaskflowHo(); + auto &tpl_lib = GetTpl(); + auto &buildcc_lib = GetBuildcc(); Reg::Toolchain(state) .Func(global_flags_cb, flatc_exe, toolchain_) .Build(build_flatc_exe_cb, flatc_exe) diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index 6cccb1f3..a6b37f19 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -37,8 +37,9 @@ namespace buildcc { * @brief Toolchain State used to selectively build and test targets */ struct ArgToolchainState { - bool build{false}; - bool test{false}; + ArgToolchainState(bool b = false, bool t = false) : build(b), test(t) {} + bool build; + bool test; }; /** @@ -47,7 +48,7 @@ struct ArgToolchainState { * Bundled with Toolchain State */ struct ArgToolchain { - ArgToolchain(){}; + ArgToolchain() = default; ArgToolchain(ToolchainId initial_id, const std::string &initial_name, const ToolchainExecutables &initial_executables) : id(initial_id), name(initial_name), executables(initial_executables) {} diff --git a/buildcc/lib/args/include/args/register.h b/buildcc/lib/args/include/args/register.h index a52a08de..25b02b24 100644 --- a/buildcc/lib/args/include/args/register.h +++ b/buildcc/lib/args/include/args/register.h @@ -201,6 +201,9 @@ class Reg::ToolchainInstance { Params &&...params) { return BuildInternal(build_cb, target, std::forward(params)...); } + template ToolchainInstance &BuildPackage(P &package) { + return Func([&]() { package.Setup(condition_); }); + } ToolchainInstance &Dep(const internal::BuilderInterface &target, const internal::BuilderInterface &dependency); ToolchainInstance &Test(const std::string &command, const BaseTarget &target, diff --git a/buildcc/lib/env/include/env/storage.h b/buildcc/lib/env/include/env/storage.h index 6ca3908b..ade21c3b 100644 --- a/buildcc/lib/env/include/env/storage.h +++ b/buildcc/lib/env/include/env/storage.h @@ -61,6 +61,8 @@ class ScopedStorage { template void Remove(T *ptr) { delete ptr; } template const T &ConstRef(const std::string &identifier) const { + env::assert_fatal(ptrs_.find(identifier) != ptrs_.end(), + fmt::format("Could not find '{}'", identifier)); const PtrMetadata &metadata = ptrs_.at(identifier); env::assert_fatal( typeid(T).name() == metadata.typeid_name, diff --git a/buildexe/buildexe.cpp b/buildexe/buildexe.cpp index 16549953..1427ab36 100644 --- a/buildexe/buildexe.cpp +++ b/buildexe/buildexe.cpp @@ -67,7 +67,8 @@ int main(int argc, char **argv) { // Build Target BuildEnvSetup build_setup(toolchain, buildexe_args); - build_setup.ConstructTarget(); + Reg::Toolchain(ArgToolchainState(true)).BuildPackage(build_setup); + Reg::Run(); // Run Target if script mode if (buildexe_args.GetBuildMode() == BuildExeMode::Script) { diff --git a/buildexe/include/buildexe/build_env_setup.h b/buildexe/include/buildexe/build_env_setup.h index f76fd9fc..afbbe321 100644 --- a/buildexe/include/buildexe/build_env_setup.h +++ b/buildexe/include/buildexe/build_env_setup.h @@ -33,11 +33,9 @@ class BuildEnvSetup { public: BuildEnvSetup(const BaseToolchain &toolchain, const BuildExeArgs &buildexe_args) - : toolchain_(toolchain), buildexe_args_(buildexe_args) { - state_.build = true; - } + : toolchain_(toolchain), buildexe_args_(buildexe_args) {} - void ConstructTarget(); + void Setup(const ArgToolchainState &state); void RunUserTarget(const ArgScriptInfo &arg_script_info); diff --git a/buildexe/src/build_env_setup.cpp b/buildexe/src/build_env_setup.cpp index 72b17fba..d36360eb 100644 --- a/buildexe/src/build_env_setup.cpp +++ b/buildexe/src/build_env_setup.cpp @@ -21,7 +21,8 @@ namespace buildcc { constexpr const char *const kTag = "BuildExe"; -void BuildEnvSetup::ConstructTarget() { +void BuildEnvSetup::Setup(const ArgToolchainState &state) { + state_ = state; if (buildexe_args_.GetBuildMode() == BuildExeMode::Script) { // buildcc and user target ConstructUserTargetWithBuildcc(); @@ -29,7 +30,6 @@ void BuildEnvSetup::ConstructTarget() { // user target ConstructUserTarget(); } - Reg::Run(); } void BuildEnvSetup::RunUserTarget(const ArgScriptInfo &arg_script_info) { diff --git a/docs/source/arch/cmake_boilerplate.rst b/docs/source/arch/cmake_boilerplate.rst index 3c418790..d4ac48cf 100644 --- a/docs/source/arch/cmake_boilerplate.rst +++ b/docs/source/arch/cmake_boilerplate.rst @@ -87,7 +87,6 @@ We can then ``add_subdirectory`` that particular folder. This helps us keep our src/assert_fatal.cpp src/logging.cpp include/env/assert_fatal.h - include/env/assert_throw.h include/env/env.h include/env/logging.h include/env/util.h diff --git a/docs/source/user_api/environment.rst b/docs/source/user_api/environment.rst index 9bbf4935..07a869af 100644 --- a/docs/source/user_api/environment.rst +++ b/docs/source/user_api/environment.rst @@ -33,19 +33,6 @@ assert_fatal.h .. doxygendefine:: ASSERT_FATAL -assert_throw.h --------------- - -.. doxygenfunction:: assert_throw([[maybe_unused]] const char *) - -.. doxygenfunction:: assert_throw(const std::string &) - -.. doxygenfunction:: assert_throw(bool, const char *) - -.. doxygenfunction:: assert_throw(bool, const std::string &) - -.. doxygendefine:: ASSERT_THROW - command.h --------- diff --git a/example/hybrid/external_lib/build.main.cpp b/example/hybrid/external_lib/build.main.cpp index d74b63ef..c2361b9e 100644 --- a/example/hybrid/external_lib/build.main.cpp +++ b/example/hybrid/external_lib/build.main.cpp @@ -5,12 +5,12 @@ using namespace buildcc; static void clean_cb(); -static void foolib_build_cb(BaseTarget &target); +static void foolib_build_cb(BaseTarget &target, const TargetInfo &foolib); constexpr const char *const EXE = "build"; int main(int argc, char **argv) { - // 1. Get arguments + // Get arguments ArgToolchain arg_gcc; ArgToolchain arg_msvc; Args::Init() @@ -18,26 +18,32 @@ int main(int argc, char **argv) { .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) .Parse(argc, argv); - // 2. Initialize your environment + // Initialize your environment Reg::Init(); - // 3. Pre-build steps + // Pre-build steps Reg::Call(Args::Clean()).Func(clean_cb); - // 4. Build steps + // Build steps Toolchain_gcc gcc; - ExecutableTarget_gcc g_foolib("cppflags", gcc, ""); - Reg::Toolchain(arg_gcc.state).Build(foolib_build_cb, g_foolib); + TargetInfo g_foo(gcc, "../foolib"); + ExecutableTarget_gcc g_external("cppflags", gcc, ""); + Reg::Toolchain(arg_gcc.state) + .Func(fooTarget, g_foo) + .Build(foolib_build_cb, g_external, g_foo); Toolchain_msvc msvc; - ExecutableTarget_msvc m_foolib("cppflags", msvc, ""); - Reg::Toolchain(arg_msvc.state).Build(foolib_build_cb, m_foolib); + ExecutableTarget_msvc m_external("cppflags", msvc, ""); + TargetInfo m_foo(gcc, "../foolib"); + Reg::Toolchain(arg_msvc.state) + .Func(fooTarget, m_foo) + .Build(foolib_build_cb, m_external, m_foo); - // 5. + // Reg::Run(); - // 6. - plugin::ClangCompileCommands({&g_foolib, &m_foolib}).Generate(); + // + plugin::ClangCompileCommands({&g_external, &m_external}).Generate(); return 0; } @@ -47,8 +53,12 @@ static void clean_cb() { fs::remove_all(Project::GetBuildDir()); } -static void foolib_build_cb(BaseTarget &target) { - fooTarget(target, "../foolib"); +static void foolib_build_cb(BaseTarget &target, const TargetInfo &foolib) { target.AddSource("main.cpp"); + target.Insert(foolib, { + SyncOption::SourceFiles, + SyncOption::HeaderFiles, + SyncOption::IncludeDirs, + }); target.Build(); } diff --git a/example/hybrid/foolib/build.foo.cpp b/example/hybrid/foolib/build.foo.cpp index 4941c2f2..56142aeb 100644 --- a/example/hybrid/foolib/build.foo.cpp +++ b/example/hybrid/foolib/build.foo.cpp @@ -1,6 +1,6 @@ #include "build.foo.h" -void fooTarget(buildcc::BaseTarget &target, const fs::path &relative_path) { - target.AddSource(relative_path / "src/foo.cpp"); - target.AddIncludeDir(relative_path / "src", true); +void fooTarget(buildcc::TargetInfo &target) { + target.AddSource("src/foo.cpp"); + target.AddIncludeDir("src", true); } diff --git a/example/hybrid/foolib/build.foo.h b/example/hybrid/foolib/build.foo.h index d53d08b5..4a741df6 100644 --- a/example/hybrid/foolib/build.foo.h +++ b/example/hybrid/foolib/build.foo.h @@ -2,4 +2,4 @@ #include "buildcc.h" -void fooTarget(buildcc::BaseTarget &target, const fs::path &relative_path); +void fooTarget(buildcc::TargetInfo &target); diff --git a/example/hybrid/foolib/build.main.cpp b/example/hybrid/foolib/build.main.cpp index aa005469..58e104e9 100644 --- a/example/hybrid/foolib/build.main.cpp +++ b/example/hybrid/foolib/build.main.cpp @@ -5,12 +5,12 @@ using namespace buildcc; static void clean_cb(); -static void foolib_build_cb(BaseTarget &target); +static void main_build_cb(BaseTarget &target, const TargetInfo &foolib); constexpr std::string_view EXE = "build"; int main(int argc, char **argv) { - // 1. Get arguments + // Get arguments ArgToolchain arg_gcc; ArgToolchain arg_msvc; Args::Init() @@ -18,26 +18,32 @@ int main(int argc, char **argv) { .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) .Parse(argc, argv); - // 2. Initialize your environment + // Initialize your environment Reg::Init(); - // 3. Pre-build steps + // Pre-build steps Reg::Call(Args::Clean()).Func(clean_cb); - // 4. Build steps + // Build steps Toolchain_gcc gcc; - ExecutableTarget_gcc g_foolib("foolib", gcc, ""); - Reg::Toolchain(arg_gcc.state).Build(foolib_build_cb, g_foolib); + TargetInfo g_foo(gcc, ""); + ExecutableTarget_gcc g_main("one_executable", gcc, ""); + Reg::Toolchain(arg_gcc.state) + .Func(fooTarget, g_foo) + .Build(main_build_cb, g_main, g_foo); Toolchain_msvc msvc; - ExecutableTarget_msvc m_foolib("foolib", msvc, ""); - Reg::Toolchain(arg_msvc.state).Build(foolib_build_cb, m_foolib); + TargetInfo m_foo(msvc, ""); + ExecutableTarget_msvc m_main("one_executable", msvc, ""); + Reg::Toolchain(arg_msvc.state) + .Func(fooTarget, m_foo) + .Build(main_build_cb, m_main, m_foo); - // 5. + // Reg::Run(); - // 6. - plugin::ClangCompileCommands({&g_foolib, &m_foolib}).Generate(); + // + plugin::ClangCompileCommands({&g_main, &m_main}).Generate(); return 0; } @@ -47,8 +53,12 @@ static void clean_cb() { fs::remove_all(Project::GetBuildDir()); } -static void foolib_build_cb(BaseTarget &target) { - fooTarget(target, ""); +static void main_build_cb(BaseTarget &target, const TargetInfo &foolib) { target.AddSource("main.cpp"); + target.Insert(foolib, { + SyncOption::SourceFiles, + SyncOption::HeaderFiles, + SyncOption::IncludeDirs, + }); target.Build(); } diff --git a/example/hybrid/generic/build.cpp b/example/hybrid/generic/build.cpp index f5631b03..27e02310 100644 --- a/example/hybrid/generic/build.cpp +++ b/example/hybrid/generic/build.cpp @@ -42,7 +42,8 @@ int main(int argc, char **argv) { // Build steps // Toolchain + Generic Target BaseToolchain toolchain = custom_toolchain.ConstructToolchain(); - Target_generic foolib_target("libfoo", default_lib_type, toolchain, ""); + Target_generic foolib_target("libfoo", default_lib_type, toolchain, + "../foolib"); Target_generic generic_target("generic", TargetType::Executable, toolchain, "src"); Reg::Toolchain(custom_toolchain.state) @@ -83,18 +84,17 @@ void args_lib_type_cb(CLI::App &app, TargetType &lib_type) { } static void foolib_build_cb(BaseTarget &foolib_target) { - fooTarget(foolib_target, Project::GetRootDir() / ".." / "foolib"); + fooTarget(foolib_target); foolib_target.Build(); } static void generic_build_cb(BaseTarget &generic_target, BaseTarget &foolib_target) { - const auto &foolib_include_dirs = foolib_target.GetIncludeDirs(); - std::for_each( - foolib_include_dirs.cbegin(), foolib_include_dirs.cend(), - [&](const fs::path &p) { generic_target.AddIncludeDir(p, true); }); - generic_target.AddLibDep(foolib_target); generic_target.AddSource("main.cpp"); + generic_target.AddLibDep(foolib_target); + generic_target.Insert(foolib_target, { + SyncOption::IncludeDirs, + }); generic_target.Build(); } diff --git a/example/hybrid/pch/build.cpp b/example/hybrid/pch/build.cpp index 88bfc426..28f3d410 100644 --- a/example/hybrid/pch/build.cpp +++ b/example/hybrid/pch/build.cpp @@ -12,7 +12,7 @@ static void cppflags_build_cb(BaseTarget &cppflags); static void cflags_build_cb(BaseTarget &cflags); int main(int argc, char **argv) { - // 1. Get arguments + // Get arguments ArgToolchain arg_gcc; ArgToolchain arg_msvc; Args::Init() @@ -20,13 +20,13 @@ int main(int argc, char **argv) { .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) .Parse(argc, argv); - // 2. Initialize your environment + // Initialize your environment Reg::Init(); - // 3. Pre-build steps + // Pre-build steps Reg::Call(Args::Clean()).Func(clean_cb); - // 4. Build steps + // Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; ExecutableTarget_gcc g_cppflags("cppflags", gcc, "files"); @@ -49,7 +49,7 @@ int main(int argc, char **argv) { Reg::Run(); - // 8. Post Build steps + // Post Build steps // - Clang Compile Commands plugin::ClangCompileCommands({&g_cflags, &g_cppflags}).Generate(); diff --git a/example/hybrid/simple/build.cpp b/example/hybrid/simple/build.cpp index 229f4f97..7dbacb3b 100644 --- a/example/hybrid/simple/build.cpp +++ b/example/hybrid/simple/build.cpp @@ -12,7 +12,7 @@ static void cppflags_build_cb(BaseTarget &cppflags); static void cflags_build_cb(BaseTarget &cflags); int main(int argc, char **argv) { - // 1. Get arguments + // Get arguments ArgToolchain arg_gcc; ArgToolchain arg_msvc; Args::Init() @@ -20,13 +20,13 @@ int main(int argc, char **argv) { .AddToolchain("msvc", "Generic msvc toolchain", arg_msvc) .Parse(argc, argv); - // 2. Initialize your environment + // Initialize your environment Reg::Init(); - // 3. Pre-build steps + // Pre-build steps Reg::Call(Args::Clean()).Func(clean_cb); - // 4. Build steps + // Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; ExecutableTarget_gcc g_cppflags("cppflags", gcc, "files"); @@ -50,7 +50,7 @@ int main(int argc, char **argv) { Reg::Run(); - // 8. Post Build steps + // Post Build steps // - Clang Compile Commands plugin::ClangCompileCommands({&g_cflags, &g_cppflags, &m_cflags, &m_cppflags}) diff --git a/example/hybrid/single/build.cpp b/example/hybrid/single/build.cpp index a6e59996..b85a774f 100644 --- a/example/hybrid/single/build.cpp +++ b/example/hybrid/single/build.cpp @@ -9,19 +9,19 @@ static void clean_cb(); static void hello_world_build_cb(BaseTarget &target); int main(int argc, char **argv) { - // 1. Get arguments + // Get arguments ArgToolchain arg_gcc; Args::Init() .AddToolchain("gcc", "Generic gcc toolchain", arg_gcc) .Parse(argc, argv); - // 2. Initialize your environment + // Initialize your environment Reg::Init(); - // 3. Pre-build steps + // Pre-build steps Reg::Call(Args::Clean()).Func(clean_cb); - // 4. Build steps + // Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; ExecutableTarget_gcc hello_world("hello_world", gcc, ""); @@ -32,10 +32,10 @@ int main(int argc, char **argv) { .Build(hello_world_build_cb, hello_world) .Test("{executable}", hello_world); - // 6. Build and Test Target + // Build and Test Target Reg::Run(); - // 8. Post Build steps + // Post Build steps // - Clang Compile Commands plugin::ClangCompileCommands({&hello_world}).Generate(); From b9b37cb48373726bd42efff1043f8df210b26ea2 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 28 Apr 2022 02:43:42 -0700 Subject: [PATCH 16/35] Toolchain generic (#209) --- bootstrap/main.buildcc.cpp | 3 +- bootstrap/src/build_buildcc.cpp | 1 + buildcc/buildcc.h | 4 + buildcc/lib/args/include/args/args.h | 46 ++- buildcc/lib/args/src/register.cpp | 22 +- buildcc/lib/env/include/env/storage.h | 54 ++- buildcc/lib/env/src/storage.cpp | 8 +- buildcc/lib/env/test/test_storage.cpp | 45 ++- .../target/src/target_info/target_info.cpp | 5 +- .../test/target/test_toolchain_flag_api.cpp | 9 +- .../include/toolchain/api/toolchain_verify.h | 42 +-- .../toolchain/include/toolchain/toolchain.h | 30 +- .../toolchain/src/api/toolchain_verify.cpp | 179 +--------- .../toolchain/test/test_toolchain_verify.cpp | 307 ++++++------------ buildcc/toolchains/CMakeLists.txt | 38 ++- .../include/toolchains/toolchain_custom.h | 36 ++ .../include/toolchains/toolchain_gcc.h | 28 +- .../include/toolchains/toolchain_generic.h | 107 ++++++ .../include/toolchains/toolchain_infos.h | 37 +++ .../include/toolchains/toolchain_mingw.h | 30 +- .../include/toolchains/toolchain_msvc.h | 29 +- buildcc/toolchains/src/toolchain_gcc.cpp | 62 ++++ buildcc/toolchains/src/toolchain_infos.cpp | 138 ++++++++ buildcc/toolchains/src/toolchain_msvc.cpp | 46 +++ buildexe/buildexe.cpp | 4 +- buildexe/include/buildexe/args_setup.h | 4 +- docs/source/examples/hybrid.rst | 3 +- docs/source/user_api/args.rst | 3 +- example/hybrid/custom_target/build.main.cpp | 6 +- example/hybrid/generic/build.cpp | 3 +- 30 files changed, 774 insertions(+), 555 deletions(-) create mode 100644 buildcc/toolchains/include/toolchains/toolchain_custom.h create mode 100644 buildcc/toolchains/include/toolchains/toolchain_generic.h create mode 100644 buildcc/toolchains/include/toolchains/toolchain_infos.h create mode 100644 buildcc/toolchains/src/toolchain_gcc.cpp create mode 100644 buildcc/toolchains/src/toolchain_infos.cpp create mode 100644 buildcc/toolchains/src/toolchain_msvc.cpp diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index a1109bf1..4adb097d 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -41,7 +41,8 @@ int main(int argc, char **argv) { Reg::Init(); Reg::Call(Args::Clean()).Func(clean_cb); - BaseToolchain toolchain = custom_toolchain_arg.ConstructToolchain(); + auto &toolchain = custom_toolchain_arg; + toolchain.SetToolchainInfoFunc(GlobalToolchainInfo::Get(toolchain.id)); BuildBuildCC buildcc( toolchain, TargetEnv(Project::GetRootDir(), Project::GetBuildDir())); diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index 4245a6cd..e655a418 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -90,6 +90,7 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, target.GlobHeaders("lib/args/include/args"); // Specialized Toolchains + target.GlobSources("toolchains/src"); target.AddIncludeDir("toolchains/include"); target.GlobHeaders("toolchains/include/toolchains"); diff --git a/buildcc/buildcc.h b/buildcc/buildcc.h index 227d9ce0..b40f5852 100644 --- a/buildcc/buildcc.h +++ b/buildcc/buildcc.h @@ -39,6 +39,10 @@ #include "toolchains/toolchain_gcc.h" #include "toolchains/toolchain_msvc.h" #include "toolchains/toolchain_mingw.h" +#include "toolchains/toolchain_generic.h" +#include "toolchains/toolchain_custom.h" + +#include "toolchains/toolchain_infos.h" // TODO, Add more specialized toolchains here diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index a6b37f19..c0937ab0 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -47,35 +47,31 @@ struct ArgToolchainState { * command line * Bundled with Toolchain State */ -struct ArgToolchain { - ArgToolchain() = default; +class ArgToolchain : public Toolchain { +public: + ArgToolchain() + : Toolchain(ToolchainId::Undefined, "", ToolchainExecutables()){}; ArgToolchain(ToolchainId initial_id, const std::string &initial_name, const ToolchainExecutables &initial_executables) - : id(initial_id), name(initial_name), executables(initial_executables) {} - ArgToolchain(ToolchainId initial_id, const std::string &initial_name, - const std::string &initial_assembler, - const std::string &initial_c_compiler, - const std::string &initial_cpp_compiler, - const std::string &initial_archiver, - const std::string &initial_linker) - : ArgToolchain(initial_id, initial_name, - ToolchainExecutables(initial_assembler, initial_c_compiler, - initial_cpp_compiler, - initial_archiver, initial_linker)) {} - - /** - * @brief Construct a BaseToolchain from the arguments supplied through the - * command line information - */ - // TODO, Update this for lock and ToolchainConfig - BaseToolchain ConstructToolchain() const { - return BaseToolchain(id, name, executables); - } + : Toolchain(initial_id, initial_name, initial_executables) {} + [[deprecated]] ArgToolchain(ToolchainId initial_id, + const std::string &initial_name, + const std::string &initial_assembler, + const std::string &initial_c_compiler, + const std::string &initial_cpp_compiler, + const std::string &initial_archiver, + const std::string &initial_linker) + : Toolchain(initial_id, initial_name, + ToolchainExecutables(initial_assembler, initial_c_compiler, + initial_cpp_compiler, initial_archiver, + initial_linker)) {} +public: ArgToolchainState state; - ToolchainId id{ToolchainId::Undefined}; - std::string name{""}; - ToolchainExecutables executables; + ToolchainId &id = RefId(); + std::string &name = RefName(); + ToolchainExecutables &executables = RefExecutables(); + ToolchainConfig &config = RefConfig(); }; // NOTE, Incomplete without pch_compile_command diff --git a/buildcc/lib/args/src/register.cpp b/buildcc/lib/args/src/register.cpp index dd042ae3..e141541c 100644 --- a/buildcc/lib/args/src/register.cpp +++ b/buildcc/lib/args/src/register.cpp @@ -23,6 +23,7 @@ #include "env/assert_fatal.h" #include "env/env.h" +#include "env/storage.h" namespace fs = std::filesystem; @@ -67,13 +68,28 @@ namespace buildcc { std::unique_ptr Reg::instance_; +void SystemInit() { + Project::Init(fs::current_path() / Args::GetProjectRootDir(), + fs::current_path() / Args::GetProjectBuildDir()); + env::set_log_level(Args::GetLogLevel()); + + // Top down (what is init first gets deinit last) + std::atexit([]() { + Project::Deinit(); + Reg::Deinit(); + Args::Deinit(); + Storage::Clear(); + }); +} + void Reg::Init() { if (!instance_) { instance_ = std::make_unique(); + env::assert_fatal(static_cast(instance_), "Reg::Init failed"); env::assert_fatal(Args::IsParsed(), "Setup your Args"); - Project::Init(fs::current_path() / Args::GetProjectRootDir(), - fs::current_path() / Args::GetProjectBuildDir()); - env::set_log_level(Args::GetLogLevel()); + + // Initialize everything else here + SystemInit(); } } diff --git a/buildcc/lib/env/include/env/storage.h b/buildcc/lib/env/include/env/storage.h index ade21c3b..21d5528e 100644 --- a/buildcc/lib/env/include/env/storage.h +++ b/buildcc/lib/env/include/env/storage.h @@ -32,13 +32,7 @@ namespace buildcc { class ScopedStorage { public: ScopedStorage() {} - ~ScopedStorage() { - for (const auto &ptr_iter : ptrs_) { - ptr_iter.second.destructor(); - } - ptrs_.clear(); - env::assert_fatal(ptrs_.empty(), "Memory not deallocated"); - } + ~ScopedStorage() { Clear(); } ScopedStorage(const ScopedStorage &) = delete; @@ -58,10 +52,15 @@ class ScopedStorage { return *ptr; } - template void Remove(T *ptr) { delete ptr; } + void Clear() { + for (const auto &ptr_iter : ptrs_) { + ptr_iter.second.destructor(); + } + ptrs_.clear(); + } template const T &ConstRef(const std::string &identifier) const { - env::assert_fatal(ptrs_.find(identifier) != ptrs_.end(), + env::assert_fatal(Contains(identifier), fmt::format("Could not find '{}'", identifier)); const PtrMetadata &metadata = ptrs_.at(identifier); env::assert_fatal( @@ -77,12 +76,30 @@ class ScopedStorage { static_cast(*this).ConstRef(identifier)); } + bool Contains(const std::string &identifier) const { + return (ptrs_.find(identifier) != ptrs_.end()); + } + + template bool Valid(const std::string &identifier) const { + if (!Contains(identifier)) { + return false; + } + const PtrMetadata &metadata = ptrs_.at(identifier); + if (typeid(T).name() != metadata.typeid_name) { + return false; + } + return true; + } + +protected: + template void Remove(T *ptr) { delete ptr; } + private: /** * @brief * @param ptr Can hold data of any type - * @param typeid_name We cannot store a template type so this is the next best - * thing + * @param typeid_name We cannot store a template type so this is the next + * best thing * @param desstructor Destructor callback to delete ptr */ struct PtrMetadata { @@ -101,14 +118,13 @@ class Storage { Storage(const Storage &) = delete; Storage(Storage &&) = delete; - static void Init() { internal_ = std::make_unique(); } - static void Deinit() { internal_.reset(nullptr); } - template static T &Add(const std::string &identifier, Params &&...params) { return Ref().Add(identifier, std::forward(params)...); } + static void Clear() { Ref().Clear(); } + template static const T &ConstRef(const std::string &identifier) { return Ref().ConstRef(identifier); @@ -118,11 +134,19 @@ class Storage { return Ref().Ref(identifier); } + static bool Contains(const std::string &identifier) { + return Ref().Contains(identifier); + } + + template static bool Valid(const std::string &identifier) { + return Ref().Valid(identifier); + } + private: static ScopedStorage &Ref(); private: - static std::unique_ptr internal_; + static ScopedStorage internal_; }; } // namespace buildcc diff --git a/buildcc/lib/env/src/storage.cpp b/buildcc/lib/env/src/storage.cpp index 6712c008..0da3ac5e 100644 --- a/buildcc/lib/env/src/storage.cpp +++ b/buildcc/lib/env/src/storage.cpp @@ -18,12 +18,8 @@ namespace buildcc { -std::unique_ptr Storage::internal_; +ScopedStorage Storage::internal_; -ScopedStorage &Storage::Ref() { - env::assert_fatal(internal_ != nullptr, - "Initialize Storage using the Storage::Init API"); - return *internal_; -} +ScopedStorage &Storage::Ref() { return internal_; } } // namespace buildcc diff --git a/buildcc/lib/env/test/test_storage.cpp b/buildcc/lib/env/test/test_storage.cpp index 929fc0ba..4c38b134 100644 --- a/buildcc/lib/env/test/test_storage.cpp +++ b/buildcc/lib/env/test/test_storage.cpp @@ -15,14 +15,23 @@ TEST_GROUP(ScopedStorageTestGroup) TEST_GROUP(StorageTestGroup) { void setup() { - buildcc::Storage::Init(); + MemoryLeakWarningPlugin::saveAndDisableNewDeleteOverloads(); } void teardown() { - buildcc::Storage::Deinit(); + buildcc::Storage::Clear(); + MemoryLeakWarningPlugin::restoreNewDeleteOverloads(); } }; // clang-format on +class MyScopedStorage : public buildcc::ScopedStorage { +public: + // We want to unit test this + template void Remove(T *ptr) { + this->ScopedStorage::Remove(ptr); + } +}; + class BigObj {}; class BigObjWithParameters { @@ -42,7 +51,7 @@ class BigObjWithParameters { static BigObj obj; TEST(ScopedStorageTestGroup, BasicUsage) { - buildcc::ScopedStorage storage; + MyScopedStorage storage; storage.Add("identifier", "name", 10, obj); storage.Add("identifier2", "name2", 12, obj); @@ -50,11 +59,21 @@ TEST(ScopedStorageTestGroup, BasicUsage) { storage.ConstRef("identifier").GetName(); storage.Ref("identifier2").GetName(); + CHECK_TRUE(storage.Contains("identifier")); + CHECK_FALSE(storage.Contains("identifier_does_not_exist")); + + CHECK_TRUE(storage.Valid("identifier")); + CHECK_FALSE(storage.Valid("wrong_identifier")); + CHECK_FALSE(storage.Valid("identifier")); + + storage.Clear(); + CHECK_FALSE(storage.Contains("identifier")); + // Automatic cleanup here } TEST(ScopedStorageTestGroup, IncorrectUsage) { - buildcc::ScopedStorage storage; + MyScopedStorage storage; storage.Add("identifier", "name", 10, obj); // We try to cast to a different type! @@ -65,13 +84,13 @@ TEST(ScopedStorageTestGroup, IncorrectUsage) { storage.Ref("identifier2")); } -std::string &toReference(std::string *pointer) { return *pointer; } - TEST(ScopedStorageTestGroup, NullptrDelete) { - buildcc::ScopedStorage storage; + MyScopedStorage storage; storage.Remove(nullptr); } +// + TEST(StorageTestGroup, BasicUsage) { buildcc::Storage::Add("identifier", "name", 10, obj); buildcc::Storage::Add("identifier2", "name2", 12, obj); @@ -84,14 +103,14 @@ TEST(StorageTestGroup, BasicUsage) { STRCMP_EQUAL(bigobj.c_str(), "name"); STRCMP_EQUAL(bigobj2.c_str(), "name2"); -} -TEST(StorageTestGroup, UsageWithoutInit) { - buildcc::Storage::Deinit(); + CHECK_TRUE(buildcc::Storage::Contains("identifier")); + CHECK_FALSE(buildcc::Storage::Contains("identifier_does_not_exist")); - CHECK_THROWS(std::exception, buildcc::Storage::Add("integer")); - CHECK_THROWS(std::exception, buildcc::Storage::Ref("integer")); - CHECK_THROWS(std::exception, buildcc::Storage::ConstRef("integer")); + CHECK_TRUE(buildcc::Storage::Valid("identifier")); + CHECK_FALSE( + buildcc::Storage::Valid("wrong_identifier")); + CHECK_FALSE(buildcc::Storage::Valid("identifier")); } int main(int ac, char **av) { diff --git a/buildcc/lib/target/src/target_info/target_info.cpp b/buildcc/lib/target/src/target_info/target_info.cpp index c338d9f6..29d94a4d 100644 --- a/buildcc/lib/target/src/target_info/target_info.cpp +++ b/buildcc/lib/target/src/target_info/target_info.cpp @@ -21,8 +21,9 @@ namespace buildcc { // PRIVATE void TargetInfo::Initialize() { - toolchain_.GetLockInfo().ExpectsLock( - "Toolchain should be locked before usage through `Toolchain::Lock`"); + // TODO, Update this later + // toolchain_.GetLockInfo().ExpectsLock( + // "Toolchain should be locked before usage through `Toolchain::Lock`"); std::for_each(toolchain_.GetPreprocessorFlags().begin(), toolchain_.GetPreprocessorFlags().end(), diff --git a/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp index dc5aa0f7..54344e46 100644 --- a/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp +++ b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp @@ -17,6 +17,7 @@ TEST_GROUP(ToolchainFlagApiTestGroup) TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Lock) { buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); + toolchain.Lock(); CHECK_THROWS(std::exception, toolchain.AddPreprocessorFlag("-preprocessor")); CHECK_THROWS(std::exception, toolchain.AddAsmCompileFlag("-asm")); CHECK_THROWS(std::exception, toolchain.AddPchCompileFlag("-pchcompile")); @@ -29,7 +30,7 @@ TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Lock) { TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Unlock) { buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld", false); + "g++", "ar", "ld"); toolchain.AddPreprocessorFlag("-preprocessor"); toolchain.AddAsmCompileFlag("-asm"); toolchain.AddPchCompileFlag("-pchcompile"); @@ -55,7 +56,7 @@ TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Unlock) { TEST(ToolchainFlagApiTestGroup, BasicTargetTest) { buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld", false); + "g++", "ar", "ld"); toolchain.AddPreprocessorFlag("-preprocessor"); toolchain.AddAsmCompileFlag("-asm"); @@ -67,7 +68,9 @@ TEST(ToolchainFlagApiTestGroup, BasicTargetTest) { toolchain.AddLinkFlag("-link"); CHECK_FALSE(toolchain.GetLockInfo().IsLocked()); - { CHECK_THROWS(std::exception, (buildcc::TargetInfo(toolchain, ""))); } + // TODO, Add this in later + // * We should lock our toolchain before using it + // { CHECK_THROWS(std::exception, (buildcc::TargetInfo(toolchain, ""))); } toolchain.Lock(); CHECK_TRUE(toolchain.GetLockInfo().IsLocked()); diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index 2ebd2423..9d545285 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -34,10 +34,6 @@ namespace fs = std::filesystem; namespace buildcc { -struct ToolchainVerifyConfig : public ToolchainFindConfig { - std::optional verification_identifier; -}; - /** * @brief Verified Toolchain information * @param path Absolute host path where ALL the toolchain executables are found @@ -55,24 +51,12 @@ struct ToolchainCompilerInfo { }; // clang-format off -typedef std::function(const ToolchainExecutables &)> ToolchainVerificationFunc; +typedef std::function(const ToolchainExecutables &)> ToolchainInfoFunc; // clang-format on template class ToolchainVerify { public: - ToolchainVerify() { Initialize(); } - - /** - * @brief - * - * @param id - * @param verification_func - * @param identifier Only read when ToolchainId::Custom is passed in - */ - static void - AddVerificationFunc(ToolchainId id, - const ToolchainVerificationFunc &verification_func, - const std::optional &op_identifier = {}); + ToolchainVerify() = default; /** * @brief Verify your toolchain executables by searching your operating system @@ -85,17 +69,23 @@ template class ToolchainVerify { * of them */ ToolchainCompilerInfo - Verify(const ToolchainVerifyConfig &config = ToolchainVerifyConfig()); + Verify(const ToolchainFindConfig &config = ToolchainFindConfig()); -protected: - ToolchainCompilerInfo verified_toolchain_; + /** + * @brief Set ToolchainInfo callback for run time objects + */ + void SetToolchainInfoFunc(const ToolchainInfoFunc &cb) { info_func_ = cb; } + const ToolchainInfoFunc &GetToolchainInfoFunc() const { return info_func_; } + +private: + /** + * @brief ToolchainInfo callback for compile time polymorphic objects + */ + virtual std::optional + GetToolchainInfo(const ToolchainExecutables &executables) const; private: - void Initialize(); - static const ToolchainVerificationFunc & - GetVerificationFunc(const std::string &identifier); - static std::unordered_map & - GetStatic(); + ToolchainInfoFunc info_func_; }; } // namespace buildcc diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 7ae3e959..4c509b28 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -17,6 +17,7 @@ #ifndef TOOLCHAIN_TOOLCHAIN_H_ #define TOOLCHAIN_TOOLCHAIN_H_ +#include #include #include #include @@ -37,22 +38,25 @@ class Toolchain : public internal::FlagApi, public ToolchainFind, public ToolchainVerify { public: -public: + // TODO, Remove ToolchainId from here Toolchain(ToolchainId id, std::string_view name, - const ToolchainExecutables &executables, bool lock = true, + const ToolchainExecutables &executables, const ToolchainConfig &config = ToolchainConfig()) - : id_(id), name_(name), executables_(executables), lock_(lock), - config_(config) { + : id_(id), name_(name), executables_(executables), config_(config), + lock_(false) { Initialize(); } - Toolchain(ToolchainId id, std::string_view name, std::string_view assembler, - std::string_view c_compiler, std::string_view cpp_compiler, - std::string_view archiver, std::string_view linker, - bool lock = true, const ToolchainConfig &config = ToolchainConfig()) + + [[deprecated]] Toolchain(ToolchainId id, std::string_view name, + std::string_view assembler, + std::string_view c_compiler, + std::string_view cpp_compiler, + std::string_view archiver, std::string_view linker, + const ToolchainConfig &config = ToolchainConfig()) : Toolchain(id, name, ToolchainExecutables(assembler, c_compiler, cpp_compiler, archiver, linker), - lock, config) {} + config) {} Toolchain(Toolchain &&) = default; Toolchain &operator=(Toolchain &&) = default; @@ -78,6 +82,12 @@ class Toolchain : public internal::FlagApi, const FunctionLock &GetLockInfo() const { return lock_; } const ToolchainConfig &GetConfig() const { return config_; } +protected: + ToolchainId &RefId() { return id_; } + std::string &RefName() { return name_; } + ToolchainExecutables &RefExecutables() { return executables_; } + ToolchainConfig &RefConfig() { return config_; } + private: struct UserSchema { std::unordered_set preprocessor_flags; @@ -103,8 +113,8 @@ class Toolchain : public internal::FlagApi, ToolchainId id_; std::string name_; ToolchainExecutables executables_; - FunctionLock lock_; ToolchainConfig config_; + FunctionLock lock_; // UserSchema user_; diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 1d60b80f..78927b65 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -35,83 +35,6 @@ namespace { -std::optional -GetGccCompilerVersion(const buildcc::env::Command &command) { - std::vector stdout_data; - bool executed = buildcc::env::Command::Execute( - command.Construct("{compiler} -dumpversion"), {}, &stdout_data); - if (!executed || stdout_data.empty()) { - return {}; - } - return stdout_data[0]; -} - -std::optional -GetGccTargetArchitecture(const buildcc::env::Command &command) { - std::vector stdout_data; - bool executed = buildcc::env::Command::Execute( - command.Construct("{compiler} -dumpmachine"), {}, &stdout_data); - if (!executed || stdout_data.empty()) { - return {}; - } - return stdout_data[0]; -} - -std::optional -GccVerificationFunc(const buildcc::ToolchainExecutables &executables) { - buildcc::env::Command command; - command.AddDefaultArgument("compiler", executables.cpp_compiler); - - auto op_compiler_version = GetGccCompilerVersion(command); - auto op_target_arch = GetGccTargetArchitecture(command); - if (!op_compiler_version.has_value() || !op_target_arch.has_value()) { - return {}; - } - - buildcc::ToolchainCompilerInfo compiler_info; - compiler_info.compiler_version = op_compiler_version.value(); - compiler_info.target_arch = op_target_arch.value(); - return compiler_info; -} - -std::optional GetMsvcCompilerVersion() { - const char *vscmd_version = getenv("VSCMD_VER"); - if (vscmd_version == nullptr) { - return {}; - } - return vscmd_version; -} - -std::optional GetMsvcTargetArchitecture() { - // DONE, Read `VSCMD_ARG_HOST_ARCH` from env path - // DONE, Read `VSCMD_ARG_TGT_ARCH` from env path - const char *vs_host_arch = getenv("VSCMD_ARG_HOST_ARCH"); - const char *vs_target_arch = getenv("VSCMD_ARG_TGT_ARCH"); - if (vs_host_arch == nullptr || vs_target_arch == nullptr) { - return {}; - } - - // DONE, Concat them - return fmt::format("{}_{}", vs_host_arch, vs_target_arch); -} - -std::optional -MsvcVerificationFunc(const buildcc::ToolchainExecutables &executables) { - (void)executables; - auto op_compiler_version = GetMsvcCompilerVersion(); - auto op_target_arch = GetMsvcTargetArchitecture(); - if (!op_compiler_version.has_value() || !op_target_arch.has_value()) { - return {}; - } - - buildcc::ToolchainCompilerInfo compiler_info; - compiler_info.compiler_version = op_compiler_version.value(); - compiler_info.target_arch = op_target_arch.value(); - return compiler_info; -} - -// - buildcc::ToolchainExecutables CreateToolchainExecutables( const fs::path &absolute_path, const buildcc::ToolchainExecutables ¤t_executables) { @@ -146,82 +69,20 @@ buildcc::ToolchainExecutables CreateToolchainExecutables( linker_path); } -std::string -GetToolchainVerifyIdentifier(buildcc::ToolchainId id, - const std::optional &op_identifier) { - std::string identifier; - switch (id) { - case buildcc::ToolchainId::Custom: - buildcc::env::assert_fatal( - op_identifier.has_value(), - "Requires verification_identifier value in ToolchainVerifyConfig"); - identifier = op_identifier.value(); - break; - case buildcc::ToolchainId::Gcc: - case buildcc::ToolchainId::Msvc: - case buildcc::ToolchainId::Clang: - case buildcc::ToolchainId::MinGW: - identifier = fmt::format("{}", id); - break; - case buildcc::ToolchainId::Undefined: - default: - buildcc::env::assert_fatal( - "Undefined toolchain. Use valid ToolchainId"); - break; - } - return identifier; -} - } // namespace namespace buildcc { -template -void ToolchainVerify::AddVerificationFunc( - ToolchainId id, const ToolchainVerificationFunc &verification_func, - const std::optional &op_identifier) { - std::string identifier; - switch (id) { - case ToolchainId::Gcc: - case ToolchainId::Msvc: - case ToolchainId::MinGW: - case ToolchainId::Clang: - identifier = fmt::format("{}", id); - break; - case ToolchainId::Custom: - env::assert_fatal(op_identifier.has_value(), - "Requires optional identifier parameter when " - "ToolchainId::Custom is defined"); - identifier = op_identifier.value(); - break; - default: - env::assert_fatal("Invalid ToolchainId parameter"); - break; - } - - env::assert_fatal( - ToolchainVerify::GetStatic().count(identifier) == 0, - fmt::format("Already registered VerificationFunction for identifier '{}'", - identifier)); - ToolchainVerify::GetStatic()[identifier] = verification_func; -} - template ToolchainCompilerInfo -ToolchainVerify::Verify(const ToolchainVerifyConfig &config) { +ToolchainVerify::Verify(const ToolchainFindConfig &config) { T &t = static_cast(*this); std::vector toolchain_paths = t.Find(config); env::assert_fatal(!toolchain_paths.empty(), "No toolchains found"); ToolchainExecutables exes = CreateToolchainExecutables(toolchain_paths[0], t.executables_); - - std::string toolchain_id_identifier = - GetToolchainVerifyIdentifier(t.GetId(), config.verification_identifier); - - const auto &verification_func = - T::GetVerificationFunc(toolchain_id_identifier); - auto op_toolchain_compiler_info = verification_func(exes); + auto op_toolchain_compiler_info = t.GetToolchainInfo(exes); env::assert_fatal(op_toolchain_compiler_info.has_value(), "Could not verify toolchain"); @@ -235,34 +96,16 @@ ToolchainVerify::Verify(const ToolchainVerifyConfig &config) { } // PRIVATE -template void ToolchainVerify::Initialize() { - static bool do_once = true; - - if (do_once) { - do_once = false; - AddVerificationFunc(ToolchainId::Gcc, GccVerificationFunc); - AddVerificationFunc(ToolchainId::Msvc, MsvcVerificationFunc); - AddVerificationFunc(ToolchainId::Clang, GccVerificationFunc); - AddVerificationFunc(ToolchainId::MinGW, GccVerificationFunc); - } -} - template -const ToolchainVerificationFunc & -ToolchainVerify::GetVerificationFunc(const std::string &identifier) { - const auto &verification_map = T::GetStatic(); - env::assert_fatal(verification_map.count(identifier) == 1, - "Add verification for custom toolchain through " - "Toolchain::AddVerificationFunc API"); - return verification_map.at(identifier); -} - -template -std::unordered_map & -ToolchainVerify::GetStatic() { - static std::unordered_map - verification_func_map; - return verification_func_map; +std::optional ToolchainVerify::GetToolchainInfo( + const ToolchainExecutables &executables) const { + const auto &cb = GetToolchainInfoFunc(); + if (cb) { + return cb(executables); + } + env::log_critical(__FUNCTION__, + "GetToolchainInfo virtual function not implemented"); + return {}; } template class ToolchainVerify; diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 5854191d..1d968392 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -2,6 +2,7 @@ #include "toolchain/toolchain.h" +#include "env/command.h" #include "env/host_os.h" #include "expect_command.h" @@ -25,11 +26,57 @@ TEST_GROUP(ToolchainVerifyTestGroup) }; // clang-format on +class MockToolchain : public buildcc::Toolchain { +public: + MockToolchain(buildcc::ToolchainId id, const std::string &name, + const buildcc::ToolchainExecutables &executables = + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", + "ld")) + : buildcc::Toolchain(id, name, executables) {} + +private: + // Example implementation + std::optional GetToolchainInfo( + const buildcc::ToolchainExecutables &executables) const override { + (void)executables; + std::vector version_stdout; + std::vector arch_stdout; + bool version_done = buildcc::env::Command::Execute("", {}, &version_stdout); + bool arch_done = buildcc::env::Command::Execute("", {}, &arch_stdout); + if (!version_done || !arch_done || version_stdout.empty() || + arch_stdout.empty()) { + return {}; + } + buildcc::ToolchainCompilerInfo info; + info.compiler_version = version_stdout[0]; + info.target_arch = arch_stdout[0]; + return info; + } +}; + // NOTE, We are mocking the environment instead of actually querying it -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc) { +TEST(ToolchainVerifyTestGroup, VerifyToolchain_BaseToolchain_Failure) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainFindConfig config; + config.env_vars.clear(); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + CHECK_THROWS(std::exception, gcc.Verify(config)); +} + +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc) { + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); + std::vector version_stdout_data{"version"}; std::vector arch_stdout_data{"arch"}; buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); @@ -43,7 +90,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc) { CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); @@ -54,8 +101,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionFailure) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); std::vector version_stdout_data{"version"}; std::vector arch_stdout_data{"arch"}; @@ -70,7 +116,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionFailure) { CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); @@ -78,8 +124,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionFailure) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionEmpty) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); std::vector version_stdout_data; std::vector arch_stdout_data{"arch"}; @@ -94,7 +139,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionEmpty) { CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); @@ -102,8 +147,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionEmpty) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchFailure) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); std::vector version_stdout_data{"version"}; std::vector arch_stdout_data{"arch"}; @@ -118,7 +162,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchFailure) { CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); @@ -126,8 +170,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchFailure) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchEmpty) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); std::vector version_stdout_data{"version"}; std::vector arch_stdout_data; @@ -142,163 +185,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchEmpty) { CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - CHECK_THROWS(std::exception, gcc.Verify(config)); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Clang) { - buildcc::Toolchain clang(buildcc::ToolchainId::Clang, "clang", "llvm-as", - "clang", "clang++", "llvm-ar", "lld"); - - std::vector version_stdout_data{"version"}; - std::vector arch_stdout_data{"arch"}; - buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); - buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); - - std::string putenv_str = fmt::format( - "CUSTOM_BUILDCC_PATH={}/toolchains/clang", fs::current_path()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - buildcc::ToolchainCompilerInfo compiler_info = clang.Verify(config); - - STRCMP_EQUAL(compiler_info.compiler_version.c_str(), "version"); - STRCMP_EQUAL(compiler_info.target_arch.c_str(), "arch"); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Msvc) { - buildcc::Toolchain msvc(buildcc::ToolchainId::Msvc, "msvc", "cl", "cl", "cl", - "lib", "link"); - // Setup ENV - // VSCMD_VER - std::string vscmd_ver = std::string("VSCMD_VER=version"); - // VSCMD_ARG_HOST_ARCH - std::string host_arch = std::string("VSCMD_ARG_HOST_ARCH=host_arch"); - // VSCMD_ARG_TGT_ARCH - std::string tgt_arch = std::string("VSCMD_ARG_TGT_ARCH=tgt_arch"); - - CHECK_TRUE(putenv(vscmd_ver.data()) == 0); - CHECK_TRUE(putenv(host_arch.data()) == 0); - CHECK_TRUE(putenv(tgt_arch.data()) == 0); - - // MSVC Compiler - std::string putenv_str = - fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/msvc", fs::current_path()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - buildcc::ToolchainCompilerInfo compiler_info = msvc.Verify(config); - - STRCMP_EQUAL(compiler_info.compiler_version.c_str(), "version"); - STRCMP_EQUAL(compiler_info.target_arch.c_str(), "host_arch_tgt_arch"); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Custom_VerificationSuccess) { - buildcc::Toolchain::AddVerificationFunc( - buildcc::ToolchainId::Custom, - [](const buildcc::ToolchainExecutables &executables) - -> std::optional { - (void)executables; - buildcc::ToolchainCompilerInfo compiler_info; - compiler_info.compiler_version = "custom_compiler_version"; - compiler_info.target_arch = "custom_target_arch"; - return compiler_info; - }, - "success_verification_func"); - buildcc::Toolchain custom(buildcc::ToolchainId::Custom, "custom", "assembler", - "c_compiler", "cpp_compiler", "archiver", "linker"); - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "toolchains" / "custom")); - config.verification_identifier = "success_verification_func"; - auto compiler_info = custom.Verify(config); - STRCMP_EQUAL(compiler_info.compiler_version.c_str(), - "custom_compiler_version"); - STRCMP_EQUAL(compiler_info.target_arch.c_str(), "custom_target_arch"); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Custom_VerificationFailure) { - buildcc::Toolchain::AddVerificationFunc( - buildcc::ToolchainId::Custom, - [](const buildcc::ToolchainExecutables &executables) - -> std::optional { - (void)executables; - return {}; - }, - "failure_verification_func"); - - // Adding verification function with the same identifier throws an exception - CHECK_THROWS(std::exception, - (buildcc::Toolchain::AddVerificationFunc( - buildcc::ToolchainId::Custom, - [](const buildcc::ToolchainExecutables &executables) - -> std::optional { - (void)executables; - return {}; - }, - "failure_verification_func"))); - buildcc::Toolchain custom(buildcc::ToolchainId::Custom, "custom", "assembler", - "c_compiler", "cpp_compiler", "archiver", "linker"); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "toolchains" / "custom")); - // Fails since ToolchainId::Custom expects a verification_identifier - CHECK_THROWS(std::exception, custom.Verify(config)); - - // Fails since we do not get valid ToolchainCompilerInfo - config.verification_identifier = "failure_verification_func"; - CHECK_THROWS(std::exception, custom.Verify(config)); - - // Fails since we have not registered a verification function with this id - config.verification_identifier = "unregistered_verification_func"; - CHECK_THROWS(std::exception, custom.Verify(config)); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Undefined_AddVerificationFunc) { - CHECK_THROWS(std::exception, - (buildcc::Toolchain::AddVerificationFunc( - buildcc::ToolchainId::Undefined, - [](const buildcc::ToolchainExecutables &executables) - -> std::optional { - (void)executables; - return {}; - }, - "undefined_verification_func"))); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadCompilerId) { - buildcc::Toolchain gcc((buildcc::ToolchainId)65535, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - std::string putenv_str = - fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); @@ -306,10 +193,9 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadCompilerId) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadAbsolutePath) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.absolute_search_paths.insert((fs::current_path() / "does_not_exist")); @@ -317,10 +203,9 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadAbsolutePath) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_PathContainsDir) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.absolute_search_paths.insert((fs::current_path() / "toolchains")); @@ -329,38 +214,6 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_PathContainsDir) { #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__MINGW64__) -TEST(ToolchainVerifyTestGroup, - VerifyToolchain_Msvc_CompilerVersionAndTargetArchFailure) { - buildcc::Toolchain msvc(buildcc::ToolchainId::Msvc, "msvc", "cl", "cl", "cl", - "lib", "link"); - // Setup ENV - // VSCMD_VER - // std::string vscmd_ver = std::string("VSCMD_VER=version"); - // // VSCMD_ARG_HOST_ARCH - // std::string host_arch = std::string("VSCMD_ARG_HOST_ARCH=host_arch"); - // // VSCMD_ARG_TGT_ARCH - // std::string tgt_arch = std::string("VSCMD_ARG_TGT_ARCH=tgt_arch"); - - // CHECK_TRUE(putenv(vscmd_ver.data()) == 0); - // CHECK_TRUE(putenv(host_arch.data()) == 0); - // CHECK_TRUE(putenv(tgt_arch.data()) == 0); - - // MSVC Compiler - std::string putenv_str = - fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/msvc", fs::current_path()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - CHECK_THROWS(std::exception, msvc.Verify(config)); -} - TEST(ToolchainVerifyTestGroup, VerifyToolchain_LockedFolder) { std::error_code err; fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::none, @@ -369,10 +222,9 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_LockedFolder) { FAIL_TEST("Could not set file permissions"); } - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.absolute_search_paths.insert( (fs::current_path() / "toolchains" / "gcc")); @@ -388,6 +240,39 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_LockedFolder) { #endif +TEST(ToolchainVerifyTestGroup, CustomToolchainInfo) { + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); + toolchain.SetToolchainInfoFunc( + [](const buildcc::ToolchainExecutables &executables) + -> std::optional { + (void)executables; + mock().actualCall("SetToolchainInfoFunc"); + buildcc::ToolchainCompilerInfo info; + info.compiler_version = "version"; + info.target_arch = "arch"; + return info; + }); + + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainFindConfig config; + config.env_vars.clear(); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + mock().expectOneCall("SetToolchainInfoFunc"); + auto info = toolchain.Verify(config); + STRCMP_EQUAL(info.compiler_version.c_str(), "version"); + STRCMP_EQUAL(info.target_arch.c_str(), "arch"); +} + int main(int ac, char **av) { buildcc::env::m::VectorStringCopier copier; mock().installCopier(TEST_VECTOR_STRING_TYPE, copier); diff --git a/buildcc/toolchains/CMakeLists.txt b/buildcc/toolchains/CMakeLists.txt index d7e8b6c3..a58b9777 100644 --- a/buildcc/toolchains/CMakeLists.txt +++ b/buildcc/toolchains/CMakeLists.txt @@ -1,36 +1,46 @@ set(TOOLCHAIN_SPECIALIZED_SRCS + src/toolchain_gcc.cpp include/toolchains/toolchain_gcc.h - include/toolchains/toolchain_msvc.h include/toolchains/toolchain_mingw.h + + src/toolchain_msvc.cpp + include/toolchains/toolchain_msvc.h + + include/toolchains/toolchain_generic.h + + src/toolchain_infos.cpp + include/toolchains/toolchain_infos.h ) if(${BUILDCC_BUILD_AS_SINGLE_LIB}) target_sources(buildcc PRIVATE ${TOOLCHAIN_SPECIALIZED_SRCS} ) - target_include_directories(buildcc INTERFACE + target_include_directories(buildcc PUBLIC $ $ ) endif() -m_clangtidy("toolchain_specialized") -add_library(toolchain_specialized INTERFACE - ${TOOLCHAIN_SPECIALIZED_SRCS} -) -target_include_directories(toolchain_specialized INTERFACE - $ - $ -) -target_link_libraries(toolchain_specialized INTERFACE - toolchain -) +if(${BUILDCC_BUILD_AS_INTERFACE}) + m_clangtidy("toolchain_specialized") + add_library(toolchain_specialized STATIC + ${TOOLCHAIN_SPECIALIZED_SRCS} + ) + target_include_directories(toolchain_specialized PUBLIC + $ + $ + ) + target_link_libraries(toolchain_specialized PUBLIC + toolchain + ) +endif() if (${BUILDCC_INSTALL}) - install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION "${BUILDCC_INSTALL_HEADER_PREFIX}") if (${BUILDCC_BUILD_AS_INTERFACE}) # toolchain_specialized Install install(TARGETS toolchain_specialized DESTINATION lib EXPORT toolchain_specializedConfig) install(EXPORT toolchain_specializedConfig DESTINATION "${BUILDCC_INSTALL_LIB_PREFIX}/toolchain_specialized") endif() + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION "${BUILDCC_INSTALL_HEADER_PREFIX}") endif() diff --git a/buildcc/toolchains/include/toolchains/toolchain_custom.h b/buildcc/toolchains/include/toolchains/toolchain_custom.h new file mode 100644 index 00000000..ba0b50bb --- /dev/null +++ b/buildcc/toolchains/include/toolchains/toolchain_custom.h @@ -0,0 +1,36 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAINS_TOOLCHAIN_CUSTOM_H_ +#define TOOLCHAINS_TOOLCHAIN_CUSTOM_H_ + +#include "toolchain/toolchain.h" + +#include + +namespace buildcc { + +class Toolchain_custom : public Toolchain { +public: + Toolchain_custom(const std::string &name, + const ToolchainExecutables &executables, + const ToolchainConfig &config = ToolchainConfig()) + : Toolchain(ToolchainId::Custom, name, executables, config) {} +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index 9e54351f..57de3c5f 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -21,12 +21,6 @@ namespace buildcc { -constexpr const char *const kGccObjExt = ".o"; -constexpr const char *const kGccPchHeaderExt = ".h"; -constexpr const char *const kGccPchCompileExt = ".gch"; -constexpr const char *const kGccPrefixIncludeDir = "-I"; -constexpr const char *const kGccPrefixLibDir = "-L"; - /** * @brief Generic GCC Toolchain
* id = ToolchainId::Gcc
@@ -39,18 +33,22 @@ constexpr const char *const kGccPrefixLibDir = "-L"; */ class Toolchain_gcc : public Toolchain { public: - Toolchain_gcc() - : Toolchain(ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld") {} + // Run time basic constructor + Toolchain_gcc(const std::string &name = "gcc", + std::optional op_executables = {}, + std::optional op_config = {}) + : Toolchain(ToolchainId::Gcc, name, + op_executables.value_or( + ToolchainExecutables("as", "gcc", "g++", "ar", "ld")), + op_config.value_or(ToolchainConfig())) {} + + virtual ~Toolchain_gcc() = default; Toolchain_gcc(const Toolchain_gcc &gcc) = delete; private: - void UpdateConfig(ToolchainConfig &config) override { - config.obj_ext = kGccObjExt; - config.pch_header_ext = kGccPchHeaderExt; - config.pch_compile_ext = kGccPchCompileExt; - config.prefix_include_dir = kGccPrefixIncludeDir; - config.prefix_lib_dir = kGccPrefixLibDir; - } + void UpdateConfig(ToolchainConfig &config) override; + std::optional + GetToolchainInfo(const ToolchainExecutables &executables) const override; }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_generic.h b/buildcc/toolchains/include/toolchains/toolchain_generic.h new file mode 100644 index 00000000..a8e0677b --- /dev/null +++ b/buildcc/toolchains/include/toolchains/toolchain_generic.h @@ -0,0 +1,107 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAINS_TOOLCHAIN_GENERIC_H_ +#define TOOLCHAINS_TOOLCHAIN_GENERIC_H_ + +#include "toolchain/toolchain.h" + +#include "toolchain_gcc.h" +#include "toolchain_mingw.h" +#include "toolchain_msvc.h" + +#include "env/storage.h" + +namespace buildcc { + +class Toolchain_generic { +public: + /** + * @brief Compile time way to create a generic toolchain instance + * + * @return Toolchain& Returns the BaseToolchain with necessary virtual + * function overrides + * Asserts fatal if ToolchainId is not supported + */ + template + static Toolchain &New(const std::string &identifier, Params &&...params) { + Toolchain *toolchain{nullptr}; + + if constexpr (id == ToolchainId::Gcc) { + toolchain = AddIf(identifier, identifier, + std::forward(params)...); + } + + if constexpr (id == ToolchainId::Msvc) { + toolchain = AddIf(identifier, identifier, + std::forward(params)...); + } + + if constexpr (id == ToolchainId::MinGW) { + toolchain = AddIf(identifier, identifier, + std::forward(params)...); + } + + env::assert_fatal(toolchain, "Toolchain could not be created"); + return *toolchain; + } + + /** + * @brief Runtime time way to create a generic toolchain instance + * + * @return Toolchain& Returns the BaseToolchain with necessary virtual + * function overrides + * Asserts fatal if ToolchainId is not supported + */ + static Toolchain &New(ToolchainId id, const std::string &identifier, + std::optional op_executables = {}, + std::optional op_config = {}) { + Toolchain *toolchain{nullptr}; + switch (id) { + case ToolchainId::Gcc: + toolchain = AddIf(identifier, identifier, op_executables, + op_config); + break; + case ToolchainId::Msvc: + toolchain = AddIf(identifier, identifier, op_executables, + op_config); + break; + case ToolchainId::MinGW: + toolchain = AddIf(identifier, identifier, op_executables, + op_config); + break; + default: + break; + } + env::assert_fatal(toolchain, "Toolchain could not be created"); + return *toolchain; + } + +private: + template + static Toolchain *AddIf(const std::string &identifier, Params &&...params) { + Toolchain *toolchain{nullptr}; + if (!Storage::Contains(identifier)) { + toolchain = + &Storage::Add(identifier, std::forward(params)...); + } + return toolchain; + } +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/toolchains/include/toolchains/toolchain_infos.h b/buildcc/toolchains/include/toolchains/toolchain_infos.h new file mode 100644 index 00000000..924b62fb --- /dev/null +++ b/buildcc/toolchains/include/toolchains/toolchain_infos.h @@ -0,0 +1,37 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAINS_TOOLCHAIN_INFOS_H_ +#define TOOLCHAINS_TOOLCHAIN_INFOS_H_ + +#include + +#include "toolchain/toolchain.h" + +namespace buildcc { + +class GlobalToolchainInfo { +public: + static const ToolchainInfoFunc &Get(ToolchainId id); + +private: + static std::unordered_map + global_toolchain_info_func_; +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index d0e76824..15f03932 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -23,12 +23,6 @@ namespace buildcc { -constexpr const char *const kMingwObjExt = ".o"; -constexpr const char *const kMingwPchHeaderExt = ".h"; -constexpr const char *const kMingwPchCompileExt = ".gch"; -constexpr const char *const kMingwPrefixIncludeDir = "-I"; -constexpr const char *const kMingwPrefixLibDir = "-L"; - /** * @brief Generic MinGW Toolchain
* id = ToolchainId::MinGW
@@ -39,20 +33,24 @@ constexpr const char *const kMingwPrefixLibDir = "-L"; * archiver = "ar"
* linker = "ld"
*/ -class Toolchain_mingw : public BaseToolchain { +class Toolchain_mingw : public Toolchain { public: - Toolchain_mingw() - : Toolchain(ToolchainId::MinGW, "gcc", "as", "gcc", "g++", "ar", "ld") {} + // Run time basic constructor + Toolchain_mingw(const std::string &name = "gcc", + std::optional op_executables = {}, + std::optional op_config = {}) + : Toolchain(ToolchainId::MinGW, name, + op_executables.value_or( + ToolchainExecutables("as", "gcc", "g++", "ar", "ld")), + op_config.value_or(ToolchainConfig())) {} + + virtual ~Toolchain_mingw() = default; Toolchain_mingw(const Toolchain_mingw &) = delete; private: - void UpdateConfig(ToolchainConfig &config) { - config.obj_ext = kMingwObjExt; - config.pch_header_ext = kMingwPchHeaderExt; - config.pch_compile_ext = kMingwPchCompileExt; - config.prefix_include_dir = kMingwPrefixIncludeDir; - config.prefix_lib_dir = kMingwPrefixLibDir; - } + void UpdateConfig(ToolchainConfig &config) override; + std::optional + GetToolchainInfo(const ToolchainExecutables &executables) const override; }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index db40a8d6..1cfb6252 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -21,13 +21,6 @@ namespace buildcc { -constexpr const char *const kMsvcObjExt = ".obj"; -constexpr const char *const kMsvcPchHeaderExt = ".h"; -constexpr const char *const kMsvcPchCompileExt = ".pch"; - -constexpr const char *const kMsvcPrefixIncludeDir = "/I"; -constexpr const char *const kMsvcPrefixLibDir = "/LIBPATH:"; - /** * @brief Generic GCC Toolchain
* id = ToolchainId::Msvc
@@ -40,18 +33,22 @@ constexpr const char *const kMsvcPrefixLibDir = "/LIBPATH:"; */ class Toolchain_msvc : public Toolchain { public: - Toolchain_msvc() - : Toolchain(ToolchainId::Msvc, "msvc", "cl", "cl", "cl", "lib", "link") {} + // Run time basic constructor + Toolchain_msvc(const std::string &name = "msvc", + std::optional op_executables = {}, + std::optional op_config = {}) + : Toolchain(ToolchainId::Msvc, name, + op_executables.value_or( + ToolchainExecutables("cl", "cl", "cl", "lib", "link")), + op_config.value_or(ToolchainConfig())) {} + + virtual ~Toolchain_msvc() = default; Toolchain_msvc(const Toolchain_msvc &gcc) = delete; private: - void UpdateConfig(ToolchainConfig &config) { - config.obj_ext = kMsvcObjExt; - config.pch_header_ext = kMsvcPchHeaderExt; - config.pch_compile_ext = kMsvcPchCompileExt; - config.prefix_include_dir = kMsvcPrefixIncludeDir; - config.prefix_lib_dir = kMsvcPrefixLibDir; - } + void UpdateConfig(ToolchainConfig &config) override; + std::optional + GetToolchainInfo(const ToolchainExecutables &executables) const override; }; } // namespace buildcc diff --git a/buildcc/toolchains/src/toolchain_gcc.cpp b/buildcc/toolchains/src/toolchain_gcc.cpp new file mode 100644 index 00000000..a99deef0 --- /dev/null +++ b/buildcc/toolchains/src/toolchain_gcc.cpp @@ -0,0 +1,62 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "toolchains/toolchain_gcc.h" +#include "toolchains/toolchain_mingw.h" + +#include "toolchains/toolchain_infos.h" + +#include "env/command.h" + +namespace { + +constexpr const char *const kGccObjExt = ".o"; +constexpr const char *const kGccPchHeaderExt = ".h"; +constexpr const char *const kGccPchCompileExt = ".gch"; +constexpr const char *const kGccPrefixIncludeDir = "-I"; +constexpr const char *const kGccPrefixLibDir = "-L"; + +void UpdateGccConfig(buildcc::ToolchainConfig &config) { + config.obj_ext = kGccObjExt; + config.pch_header_ext = kGccPchHeaderExt; + config.pch_compile_ext = kGccPchCompileExt; + config.prefix_include_dir = kGccPrefixIncludeDir; + config.prefix_lib_dir = kGccPrefixLibDir; +} + +} // namespace + +namespace buildcc { + +void Toolchain_gcc::UpdateConfig(ToolchainConfig &config) { + UpdateGccConfig(config); +} + +std::optional +Toolchain_gcc::GetToolchainInfo(const ToolchainExecutables &executables) const { + return GlobalToolchainInfo::Get(ToolchainId::Gcc)(executables); +} + +void Toolchain_mingw::UpdateConfig(ToolchainConfig &config) { + UpdateGccConfig(config); +} + +std::optional Toolchain_mingw::GetToolchainInfo( + const ToolchainExecutables &executables) const { + return GlobalToolchainInfo::Get(ToolchainId::MinGW)(executables); +} + +} // namespace buildcc diff --git a/buildcc/toolchains/src/toolchain_infos.cpp b/buildcc/toolchains/src/toolchain_infos.cpp new file mode 100644 index 00000000..49117e66 --- /dev/null +++ b/buildcc/toolchains/src/toolchain_infos.cpp @@ -0,0 +1,138 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "toolchains/toolchain_infos.h" + +#include "env/assert_fatal.h" +#include "env/command.h" +#include "env/logging.h" + +namespace { + +// GCC + +std::optional +GetGccCompilerVersion(const buildcc::env::Command &command) { + std::vector stdout_data; + bool executed = buildcc::env::Command::Execute( + command.Construct("{compiler} -dumpversion"), {}, &stdout_data); + if (!executed || stdout_data.empty()) { + return {}; + } + return stdout_data[0]; +} + +std::optional +GetGccTargetArchitecture(const buildcc::env::Command &command) { + std::vector stdout_data; + bool executed = buildcc::env::Command::Execute( + command.Construct("{compiler} -dumpmachine"), {}, &stdout_data); + if (!executed || stdout_data.empty()) { + return {}; + } + return stdout_data[0]; +} + +std::optional +GetGccToolchainInfo(const buildcc::ToolchainExecutables &executables) { + buildcc::env::Command command; + command.AddDefaultArgument("compiler", executables.cpp_compiler); + + auto op_compiler_version = GetGccCompilerVersion(command); + auto op_target_arch = GetGccTargetArchitecture(command); + if (!op_compiler_version.has_value() || !op_target_arch.has_value()) { + return {}; + } + + buildcc::ToolchainCompilerInfo compiler_info; + compiler_info.compiler_version = op_compiler_version.value(); + compiler_info.target_arch = op_target_arch.value(); + return compiler_info; +} + +// MSVC + +std::optional GetMsvcCompilerVersion() { + const char *vscmd_version = getenv("VSCMD_VER"); + if (vscmd_version == nullptr) { + return {}; + } + return vscmd_version; +} + +std::optional GetMsvcTargetArchitecture() { + // DONE, Read `VSCMD_ARG_HOST_ARCH` from env path + // DONE, Read `VSCMD_ARG_TGT_ARCH` from env path + const char *vs_host_arch = getenv("VSCMD_ARG_HOST_ARCH"); + const char *vs_target_arch = getenv("VSCMD_ARG_TGT_ARCH"); + if (vs_host_arch == nullptr || vs_target_arch == nullptr) { + return {}; + } + + // DONE, Concat them + return fmt::format("{}_{}", vs_host_arch, vs_target_arch); +} + +std::optional +GetMsvcToolchainInfo(const buildcc::ToolchainExecutables &executables) { + (void)executables; + auto op_compiler_version = GetMsvcCompilerVersion(); + auto op_target_arch = GetMsvcTargetArchitecture(); + if (!op_compiler_version.has_value() || !op_target_arch.has_value()) { + return {}; + } + + buildcc::ToolchainCompilerInfo compiler_info; + compiler_info.compiler_version = op_compiler_version.value(); + compiler_info.target_arch = op_target_arch.value(); + return compiler_info; +} + +// + +std::optional +GetErrorToolchainInfo(const buildcc::ToolchainExecutables &executables) { + (void)executables; + buildcc::env::log_critical(__FUNCTION__, + "ToolchainInfo does not exist for particular " + "ToolchainId. Supply your own through 3 methods."); + return {}; +} + +} // namespace + +namespace buildcc { + +// TODO, Shift this to toolchain.h +// Create a global_toolchain.h file which manages global toolchain state +std::unordered_map + GlobalToolchainInfo::global_toolchain_info_func_{ + {ToolchainId::Gcc, GetGccToolchainInfo}, + {ToolchainId::MinGW, GetGccToolchainInfo}, + {ToolchainId::Clang, GetGccToolchainInfo}, + {ToolchainId::Msvc, GetMsvcToolchainInfo}, + {ToolchainId::Custom, GetErrorToolchainInfo}, + {ToolchainId::Undefined, GetErrorToolchainInfo}, + }; + +const ToolchainInfoFunc &GlobalToolchainInfo::Get(ToolchainId id) { + env::assert_fatal(global_toolchain_info_func_.find(id) != + global_toolchain_info_func_.end(), + "Invalid ToolchainId"); + return global_toolchain_info_func_[id]; +} + +} // namespace buildcc diff --git a/buildcc/toolchains/src/toolchain_msvc.cpp b/buildcc/toolchains/src/toolchain_msvc.cpp new file mode 100644 index 00000000..a6eca961 --- /dev/null +++ b/buildcc/toolchains/src/toolchain_msvc.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "toolchains/toolchain_msvc.h" + +#include "toolchains/toolchain_infos.h" + +namespace { + +constexpr const char *const kMsvcObjExt = ".obj"; +constexpr const char *const kMsvcPchHeaderExt = ".h"; +constexpr const char *const kMsvcPchCompileExt = ".pch"; +constexpr const char *const kMsvcPrefixIncludeDir = "/I"; +constexpr const char *const kMsvcPrefixLibDir = "/LIBPATH:"; + +} // namespace + +namespace buildcc { + +void Toolchain_msvc::UpdateConfig(ToolchainConfig &config) { + config.obj_ext = kMsvcObjExt; + config.pch_header_ext = kMsvcPchHeaderExt; + config.pch_compile_ext = kMsvcPchCompileExt; + config.prefix_include_dir = kMsvcPrefixIncludeDir; + config.prefix_lib_dir = kMsvcPrefixLibDir; +} + +std::optional Toolchain_msvc::GetToolchainInfo( + const ToolchainExecutables &executables) const { + return GlobalToolchainInfo::Get(ToolchainId::Msvc)(executables); +} + +} // namespace buildcc diff --git a/buildexe/buildexe.cpp b/buildexe/buildexe.cpp index 1427ab36..31715ec9 100644 --- a/buildexe/buildexe.cpp +++ b/buildexe/buildexe.cpp @@ -57,8 +57,8 @@ int main(int argc, char **argv) { Reg::Call(Args::Clean()).Func(clean_cb); // Host Toolchain - BaseToolchain toolchain = - buildexe_args.GetHostToolchainArg().ConstructToolchain(); + auto &toolchain = buildexe_args.GetHostToolchainArg(); + toolchain.SetToolchainInfoFunc(GlobalToolchainInfo::Get(toolchain.id)); toolchain.Verify(); if (buildexe_args.GetBuildMode() == BuildExeMode::Script) { diff --git a/buildexe/include/buildexe/args_setup.h b/buildexe/include/buildexe/args_setup.h index dde67f08..980ee696 100644 --- a/buildexe/include/buildexe/args_setup.h +++ b/buildexe/include/buildexe/args_setup.h @@ -77,9 +77,7 @@ class BuildExeArgs { void Setup(int argc, char **argv); // Getters - const ArgToolchain &GetHostToolchainArg() const { - return host_toolchain_arg_; - } + ArgToolchain &GetHostToolchainArg() { return host_toolchain_arg_; } const ArgTargetInfo &GetTargetInfo() const { return out_targetinfo_; } const ArgTargetInputs &GetTargetInputs() const { return out_targetinputs_; } const ArgScriptInfo &GetScriptInfo() const { return out_scriptinfo_; } diff --git a/docs/source/examples/hybrid.rst b/docs/source/examples/hybrid.rst index 38c611a8..b79b802d 100644 --- a/docs/source/examples/hybrid.rst +++ b/docs/source/examples/hybrid.rst @@ -352,7 +352,8 @@ For super customized targets and toolchains Toolchain_gcc gcc; Toolchain_msvc msvc; // Get custom toolchain from the command line, supplied at run time - BaseToolchain clang = toolchain_clang_gnu.ConstructToolchain(); + auto &clang = toolchain_clang_gnu; + clang.SetToolchainInfoFunc(GlobalToolchainInfo::Get(clang.id)); ExecutableTarget_gcc g_foolib("foolib", gcc, ""); ExecutableTarget_msvc m_foolib("foolib", msvc, ""); diff --git a/docs/source/user_api/args.rst b/docs/source/user_api/args.rst index e21db691..6f7e027a 100644 --- a/docs/source/user_api/args.rst +++ b/docs/source/user_api/args.rst @@ -54,7 +54,8 @@ Example // .build, .test arg_gcc_toolchain.state; // .id, .name, .asm_compiler, .c_compiler, .cpp_compiler, .archiver, .linker -> BaseToolchain - BaseToolchain gcc_toolchain = arg_gcc_toolchain.ConstructToolchain(); + auto &gcc_toolchain = arg_gcc_toolchain; + gcc_toolchain.SetToolchainInfoFunc(GlobalToolchainInfo::Get(gcc_toolchain.id)); return 0; } diff --git a/example/hybrid/custom_target/build.main.cpp b/example/hybrid/custom_target/build.main.cpp index c93b618c..82b03727 100644 --- a/example/hybrid/custom_target/build.main.cpp +++ b/example/hybrid/custom_target/build.main.cpp @@ -36,11 +36,11 @@ int main(int argc, char **argv) { Reg::Toolchain(arg_msvc.state).Build(foolib_build_cb, m_foolib); // * NOTE, This is how we add our custom toolchain - BaseToolchain clang = arg_toolchain_clang_gnu.ConstructToolchain(); + auto &clang = arg_toolchain_clang_gnu; + clang.SetToolchainInfoFunc(GlobalToolchainInfo::Get(clang.id)); Target_custom c_foolib("CFoolib.exe", TargetType::Executable, clang, "", arg_target_clang_gnu.GetTargetConfig()); - Reg::Toolchain(arg_toolchain_clang_gnu.state) - .Build(foolib_build_cb, c_foolib); + Reg::Toolchain(clang.state).Build(foolib_build_cb, c_foolib); // Reg::Run(); diff --git a/example/hybrid/generic/build.cpp b/example/hybrid/generic/build.cpp index 27e02310..a6c28d0d 100644 --- a/example/hybrid/generic/build.cpp +++ b/example/hybrid/generic/build.cpp @@ -41,7 +41,8 @@ int main(int argc, char **argv) { // Build steps // Toolchain + Generic Target - BaseToolchain toolchain = custom_toolchain.ConstructToolchain(); + auto &toolchain = custom_toolchain; + toolchain.SetToolchainInfoFunc(GlobalToolchainInfo::Get(toolchain.id)); Target_generic foolib_target("libfoo", default_lib_type, toolchain, "../foolib"); Target_generic generic_target("generic", TargetType::Executable, toolchain, From 19fcd4ed09527b490f5ac956f3b868f827384616 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 30 Apr 2022 03:22:13 -0700 Subject: [PATCH 17/35] `Toolchain specialized` added as a dependency to `Args` (#210) --- bootstrap/main.buildcc.cpp | 4 +- buildcc/buildcc.h | 10 +- buildcc/lib/args/CMakeLists.txt | 3 + buildcc/lib/args/include/args/args.h | 36 +- buildcc/lib/args/src/args.cpp | 5 + .../include/toolchain/api/toolchain_verify.h | 15 +- .../toolchain/include/toolchain/toolchain.h | 10 +- .../toolchain/src/api/toolchain_verify.cpp | 18 +- .../lib/toolchain/src/toolchain/toolchain.cpp | 7 +- .../toolchain/test/test_toolchain_verify.cpp | 148 +------ buildcc/toolchains/CMakeLists.txt | 35 +- .../include/toolchains/toolchain_custom.h | 18 +- .../include/toolchains/toolchain_gcc.h | 10 +- .../include/toolchains/toolchain_generic.h | 76 +--- .../include/toolchains/toolchain_infos.h | 22 +- .../include/toolchains/toolchain_mingw.h | 8 +- .../include/toolchains/toolchain_msvc.h | 10 +- .../toolchains/toolchain_specialized.h | 32 ++ .../toolchains/src/toolchain_aggregate.cpp | 86 ++++ buildcc/toolchains/src/toolchain_gcc.cpp | 38 +- buildcc/toolchains/src/toolchain_infos.cpp | 77 +++- buildcc/toolchains/src/toolchain_msvc.cpp | 24 +- .../test/test_toolchain_specialized.cpp | 383 ++++++++++++++++++ buildexe/buildexe.cpp | 3 +- docs/source/user_api/args.rst | 2 +- docs/source/user_api/toolchain.rst | 2 - example/hybrid/custom_target/build.main.cpp | 6 +- example/hybrid/generic/build.cpp | 3 +- 28 files changed, 705 insertions(+), 386 deletions(-) create mode 100644 buildcc/toolchains/include/toolchains/toolchain_specialized.h create mode 100644 buildcc/toolchains/src/toolchain_aggregate.cpp create mode 100644 buildcc/toolchains/test/test_toolchain_specialized.cpp diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index 4adb097d..4e8738fd 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -41,9 +41,7 @@ int main(int argc, char **argv) { Reg::Init(); Reg::Call(Args::Clean()).Func(clean_cb); - auto &toolchain = custom_toolchain_arg; - toolchain.SetToolchainInfoFunc(GlobalToolchainInfo::Get(toolchain.id)); - + auto &toolchain = custom_toolchain_arg.ConstructToolchain(); BuildBuildCC buildcc( toolchain, TargetEnv(Project::GetRootDir(), Project::GetBuildDir())); auto &buildcc_lib = buildcc.GetBuildcc(); diff --git a/buildcc/buildcc.h b/buildcc/buildcc.h index b40f5852..8f08c5db 100644 --- a/buildcc/buildcc.h +++ b/buildcc/buildcc.h @@ -36,15 +36,7 @@ #include "target/target.h" // Specialized Toolchain -#include "toolchains/toolchain_gcc.h" -#include "toolchains/toolchain_msvc.h" -#include "toolchains/toolchain_mingw.h" -#include "toolchains/toolchain_generic.h" -#include "toolchains/toolchain_custom.h" - -#include "toolchains/toolchain_infos.h" - -// TODO, Add more specialized toolchains here +#include "toolchains/toolchain_specialized.h" // Specialized Targets #include "targets/target_gcc.h" diff --git a/buildcc/lib/args/CMakeLists.txt b/buildcc/lib/args/CMakeLists.txt index 6535b1f3..04b82e0d 100644 --- a/buildcc/lib/args/CMakeLists.txt +++ b/buildcc/lib/args/CMakeLists.txt @@ -20,6 +20,7 @@ target_link_libraries(mock_args PUBLIC CLI11::CLI11 mock_target + mock_toolchain_specialized CppUTest CppUTestExt @@ -82,6 +83,8 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) ) target_link_libraries(args PRIVATE target + + toolchain_specialized ) target_compile_options(args PRIVATE ${BUILD_COMPILE_FLAGS}) target_link_options(args PRIVATE ${BUILD_LINK_FLAGS}) diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index c0937ab0..bb32faf3 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -25,7 +25,7 @@ // BuildCC #include "env/logging.h" -#include "toolchain/toolchain.h" +#include "toolchains/toolchain_specialized.h" #include "target/common/target_config.h" @@ -47,31 +47,27 @@ struct ArgToolchainState { * command line * Bundled with Toolchain State */ -class ArgToolchain : public Toolchain { +class ArgToolchain { public: ArgToolchain() - : Toolchain(ToolchainId::Undefined, "", ToolchainExecutables()){}; + : ArgToolchain(ToolchainId::Undefined, "", ToolchainExecutables(), + ToolchainConfig()) {} ArgToolchain(ToolchainId initial_id, const std::string &initial_name, - const ToolchainExecutables &initial_executables) - : Toolchain(initial_id, initial_name, initial_executables) {} - [[deprecated]] ArgToolchain(ToolchainId initial_id, - const std::string &initial_name, - const std::string &initial_assembler, - const std::string &initial_c_compiler, - const std::string &initial_cpp_compiler, - const std::string &initial_archiver, - const std::string &initial_linker) - : Toolchain(initial_id, initial_name, - ToolchainExecutables(initial_assembler, initial_c_compiler, - initial_cpp_compiler, initial_archiver, - initial_linker)) {} + const ToolchainExecutables &initial_executables, + const ToolchainConfig &initial_config) + : id(initial_id), name(initial_name), executables(initial_executables), + config(initial_config) {} + + Toolchain &ConstructToolchain() { + return Toolchain_generic::New(id, name, executables, config); + } public: ArgToolchainState state; - ToolchainId &id = RefId(); - std::string &name = RefName(); - ToolchainExecutables &executables = RefExecutables(); - ToolchainConfig &config = RefConfig(); + ToolchainId id; + std::string name; + ToolchainExecutables executables; + ToolchainConfig config; }; // NOTE, Incomplete without pch_compile_command diff --git a/buildcc/lib/args/src/args.cpp b/buildcc/lib/args/src/args.cpp index 0d10823c..ce0b05c3 100644 --- a/buildcc/lib/args/src/args.cpp +++ b/buildcc/lib/args/src/args.cpp @@ -170,9 +170,12 @@ Args::Instance &Args::Instance::AddToolchain(const std::string &name, CLI::App *toolchain = RefInternal().toolchain; CLI::App *t_user = toolchain->add_subcommand(name, description)->group(kToolchainGroup); + + // State t_user->add_flag(kToolchainBuildParam, out.state.build); t_user->add_flag(kToolchainTestParam, out.state.test); + // Id, Name, Executables t_user->add_option(kToolchainIdParam, out.id, kToolchainIdDesc) ->transform(CLI::CheckedTransformer(kToolchainIdMap, CLI::ignore_case)) ->default_val(initial.id); @@ -187,6 +190,8 @@ Args::Instance &Args::Instance::AddToolchain(const std::string &name, ->default_val(initial.executables.archiver); t_user->add_option(kToolchainLinkerParam, out.executables.linker) ->default_val(initial.executables.linker); + + // TODO, Add toolchain config return *this; } diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index 9d545285..6bd916f7 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -51,7 +51,7 @@ struct ToolchainCompilerInfo { }; // clang-format off -typedef std::function(const ToolchainExecutables &)> ToolchainInfoFunc; +typedef std::function(const ToolchainExecutables &)> ToolchainInfoCb; // clang-format on template class ToolchainVerify { @@ -74,18 +74,11 @@ template class ToolchainVerify { /** * @brief Set ToolchainInfo callback for run time objects */ - void SetToolchainInfoFunc(const ToolchainInfoFunc &cb) { info_func_ = cb; } - const ToolchainInfoFunc &GetToolchainInfoFunc() const { return info_func_; } + void SetToolchainInfoCb(const ToolchainInfoCb &cb) { info_cb_ = cb; } + const ToolchainInfoCb &GetToolchainInfoCb() const { return info_cb_; } private: - /** - * @brief ToolchainInfo callback for compile time polymorphic objects - */ - virtual std::optional - GetToolchainInfo(const ToolchainExecutables &executables) const; - -private: - ToolchainInfoFunc info_func_; + ToolchainInfoCb info_cb_; }; } // namespace buildcc diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 4c509b28..41c92137 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -43,9 +43,7 @@ class Toolchain : public internal::FlagApi, const ToolchainExecutables &executables, const ToolchainConfig &config = ToolchainConfig()) : id_(id), name_(name), executables_(executables), config_(config), - lock_(false) { - Initialize(); - } + lock_(false) {} [[deprecated]] Toolchain(ToolchainId id, std::string_view name, std::string_view assembler, @@ -58,6 +56,7 @@ class Toolchain : public internal::FlagApi, archiver, linker), config) {} + virtual ~Toolchain() = default; Toolchain(Toolchain &&) = default; Toolchain &operator=(Toolchain &&) = default; Toolchain(const Toolchain &) = delete; @@ -100,11 +99,6 @@ class Toolchain : public internal::FlagApi, std::unordered_set link_flags; }; -private: - void Initialize(); - - virtual void UpdateConfig(ToolchainConfig &config); - private: friend class internal::FlagApi; friend class ToolchainVerify; diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 78927b65..4c22aab2 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -82,7 +82,10 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { ToolchainExecutables exes = CreateToolchainExecutables(toolchain_paths[0], t.executables_); - auto op_toolchain_compiler_info = t.GetToolchainInfo(exes); + std::optional op_toolchain_compiler_info{}; + if (GetToolchainInfoCb()) { + op_toolchain_compiler_info = GetToolchainInfoCb()(exes); + } env::assert_fatal(op_toolchain_compiler_info.has_value(), "Could not verify toolchain"); @@ -95,19 +98,6 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { return toolchain_compiler_info; } -// PRIVATE -template -std::optional ToolchainVerify::GetToolchainInfo( - const ToolchainExecutables &executables) const { - const auto &cb = GetToolchainInfoFunc(); - if (cb) { - return cb(executables); - } - env::log_critical(__FUNCTION__, - "GetToolchainInfo virtual function not implemented"); - return {}; -} - template class ToolchainVerify; } // namespace buildcc diff --git a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp index 53bee71c..55889c02 100644 --- a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp +++ b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp @@ -16,13 +16,10 @@ #include "toolchain/toolchain.h" -namespace buildcc { +#include -void Toolchain::Initialize() { UpdateConfig(config_); } +namespace buildcc { void Toolchain::Lock() { lock_.Lock(); } -// PRIVATE -void Toolchain::UpdateConfig(ToolchainConfig &config) { (void)config; } - } // namespace buildcc diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 1d968392..19110e05 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -33,149 +33,13 @@ class MockToolchain : public buildcc::Toolchain { buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")) : buildcc::Toolchain(id, name, executables) {} - -private: - // Example implementation - std::optional GetToolchainInfo( - const buildcc::ToolchainExecutables &executables) const override { - (void)executables; - std::vector version_stdout; - std::vector arch_stdout; - bool version_done = buildcc::env::Command::Execute("", {}, &version_stdout); - bool arch_done = buildcc::env::Command::Execute("", {}, &arch_stdout); - if (!version_done || !arch_done || version_stdout.empty() || - arch_stdout.empty()) { - return {}; - } - buildcc::ToolchainCompilerInfo info; - info.compiler_version = version_stdout[0]; - info.target_arch = arch_stdout[0]; - return info; - } }; // NOTE, We are mocking the environment instead of actually querying it TEST(ToolchainVerifyTestGroup, VerifyToolchain_BaseToolchain_Failure) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - std::string putenv_str = - fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainFindConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - CHECK_THROWS(std::exception, gcc.Verify(config)); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc) { - MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); - - std::vector version_stdout_data{"version"}; - std::vector arch_stdout_data{"arch"}; - buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); - buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); - - std::string putenv_str = - fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainFindConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - buildcc::ToolchainCompilerInfo compiler_info = gcc.Verify(config); - - STRCMP_EQUAL(compiler_info.compiler_version.c_str(), "version"); - STRCMP_EQUAL(compiler_info.target_arch.c_str(), "arch"); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionFailure) { - MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); - - std::vector version_stdout_data{"version"}; - std::vector arch_stdout_data{"arch"}; - buildcc::env::m::CommandExpect_Execute(1, false, &version_stdout_data); - buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); - - std::string putenv_str = - fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainFindConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - CHECK_THROWS(std::exception, gcc.Verify(config)); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionEmpty) { - MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); - - std::vector version_stdout_data; - std::vector arch_stdout_data{"arch"}; - buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); - buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); - - std::string putenv_str = - fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainFindConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - CHECK_THROWS(std::exception, gcc.Verify(config)); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchFailure) { - MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); - - std::vector version_stdout_data{"version"}; - std::vector arch_stdout_data{"arch"}; - buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); - buildcc::env::m::CommandExpect_Execute(1, false, &arch_stdout_data); - - std::string putenv_str = - fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainFindConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - CHECK_THROWS(std::exception, gcc.Verify(config)); -} - -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchEmpty) { - MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); - - std::vector version_stdout_data{"version"}; - std::vector arch_stdout_data; - buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); - buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); + MockToolchain gcc( + buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); @@ -244,11 +108,11 @@ TEST(ToolchainVerifyTestGroup, CustomToolchainInfo) { buildcc::Toolchain toolchain( buildcc::ToolchainId::Gcc, "gcc", buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); - toolchain.SetToolchainInfoFunc( + toolchain.SetToolchainInfoCb( [](const buildcc::ToolchainExecutables &executables) -> std::optional { (void)executables; - mock().actualCall("SetToolchainInfoFunc"); + mock().actualCall("SetToolchainInfoCb"); buildcc::ToolchainCompilerInfo info; info.compiler_version = "version"; info.target_arch = "arch"; @@ -267,7 +131,7 @@ TEST(ToolchainVerifyTestGroup, CustomToolchainInfo) { config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - mock().expectOneCall("SetToolchainInfoFunc"); + mock().expectOneCall("SetToolchainInfoCb"); auto info = toolchain.Verify(config); STRCMP_EQUAL(info.compiler_version.c_str(), "version"); STRCMP_EQUAL(info.target_arch.c_str(), "arch"); diff --git a/buildcc/toolchains/CMakeLists.txt b/buildcc/toolchains/CMakeLists.txt index a58b9777..4bb1a8c2 100644 --- a/buildcc/toolchains/CMakeLists.txt +++ b/buildcc/toolchains/CMakeLists.txt @@ -1,4 +1,7 @@ set(TOOLCHAIN_SPECIALIZED_SRCS + src/toolchain_infos.cpp + include/toolchains/toolchain_infos.h + src/toolchain_gcc.cpp include/toolchains/toolchain_gcc.h include/toolchains/toolchain_mingw.h @@ -6,12 +9,40 @@ set(TOOLCHAIN_SPECIALIZED_SRCS src/toolchain_msvc.cpp include/toolchains/toolchain_msvc.h + src/toolchain_aggregate.cpp include/toolchains/toolchain_generic.h + include/toolchains/toolchain_custom.h - src/toolchain_infos.cpp - include/toolchains/toolchain_infos.h + include/toolchains/toolchain_specialized.h ) +if (${TESTING}) + add_library(mock_toolchain_specialized + ${TOOLCHAIN_SPECIALIZED_SRCS} + ) + target_include_directories(mock_toolchain_specialized PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + target_compile_options(mock_toolchain_specialized PUBLIC + ${TEST_COMPILE_FLAGS} ${BUILD_COMPILE_FLAGS} + ) + target_link_options(mock_toolchain_specialized PUBLIC + ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS} + ) + target_link_libraries(mock_toolchain_specialized PUBLIC + mock_toolchain + + CppUTest + CppUTestExt + ${TEST_LINK_LIBS} + ) + + add_executable(test_toolchain_specialized test/test_toolchain_specialized) + target_link_libraries(test_toolchain_specialized PRIVATE mock_toolchain_specialized) + + add_test(NAME test_toolchain_specialized COMMAND test_toolchain_specialized) +endif() + if(${BUILDCC_BUILD_AS_SINGLE_LIB}) target_sources(buildcc PRIVATE ${TOOLCHAIN_SPECIALIZED_SRCS} diff --git a/buildcc/toolchains/include/toolchains/toolchain_custom.h b/buildcc/toolchains/include/toolchains/toolchain_custom.h index ba0b50bb..bf061697 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_custom.h +++ b/buildcc/toolchains/include/toolchains/toolchain_custom.h @@ -19,16 +19,24 @@ #include "toolchain/toolchain.h" -#include - namespace buildcc { class Toolchain_custom : public Toolchain { public: - Toolchain_custom(const std::string &name, + // Run time basic constructor + Toolchain_custom(ToolchainId id, const std::string &name, const ToolchainExecutables &executables, - const ToolchainConfig &config = ToolchainConfig()) - : Toolchain(ToolchainId::Custom, name, executables, config) {} + std::optional op_config = {}) + : Toolchain(id, name, executables, + op_config.value_or(ToolchainConfig())) { + Initialize(); + } + + virtual ~Toolchain_custom() = default; + Toolchain_custom(const Toolchain_custom &) = delete; + +private: + void Initialize(); }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index 57de3c5f..22764d96 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -40,15 +40,15 @@ class Toolchain_gcc : public Toolchain { : Toolchain(ToolchainId::Gcc, name, op_executables.value_or( ToolchainExecutables("as", "gcc", "g++", "ar", "ld")), - op_config.value_or(ToolchainConfig())) {} + op_config.value_or(ToolchainConfig())) { + Initialize(); + } virtual ~Toolchain_gcc() = default; - Toolchain_gcc(const Toolchain_gcc &gcc) = delete; + Toolchain_gcc(const Toolchain_gcc &) = delete; private: - void UpdateConfig(ToolchainConfig &config) override; - std::optional - GetToolchainInfo(const ToolchainExecutables &executables) const override; + void Initialize(); }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_generic.h b/buildcc/toolchains/include/toolchains/toolchain_generic.h index a8e0677b..75b835f4 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_generic.h +++ b/buildcc/toolchains/include/toolchains/toolchain_generic.h @@ -19,87 +19,21 @@ #include "toolchain/toolchain.h" -#include "toolchain_gcc.h" -#include "toolchain_mingw.h" -#include "toolchain_msvc.h" - -#include "env/storage.h" - namespace buildcc { class Toolchain_generic { public: /** - * @brief Compile time way to create a generic toolchain instance - * - * @return Toolchain& Returns the BaseToolchain with necessary virtual - * function overrides - * Asserts fatal if ToolchainId is not supported - */ - template - static Toolchain &New(const std::string &identifier, Params &&...params) { - Toolchain *toolchain{nullptr}; - - if constexpr (id == ToolchainId::Gcc) { - toolchain = AddIf(identifier, identifier, - std::forward(params)...); - } - - if constexpr (id == ToolchainId::Msvc) { - toolchain = AddIf(identifier, identifier, - std::forward(params)...); - } - - if constexpr (id == ToolchainId::MinGW) { - toolchain = AddIf(identifier, identifier, - std::forward(params)...); - } - - env::assert_fatal(toolchain, "Toolchain could not be created"); - return *toolchain; - } - - /** - * @brief Runtime time way to create a generic toolchain instance + * @brief Create a generic toolchain instance * * @return Toolchain& Returns the BaseToolchain with necessary virtual * function overrides * Asserts fatal if ToolchainId is not supported */ - static Toolchain &New(ToolchainId id, const std::string &identifier, - std::optional op_executables = {}, - std::optional op_config = {}) { - Toolchain *toolchain{nullptr}; - switch (id) { - case ToolchainId::Gcc: - toolchain = AddIf(identifier, identifier, op_executables, - op_config); - break; - case ToolchainId::Msvc: - toolchain = AddIf(identifier, identifier, op_executables, - op_config); - break; - case ToolchainId::MinGW: - toolchain = AddIf(identifier, identifier, op_executables, - op_config); - break; - default: - break; - } - env::assert_fatal(toolchain, "Toolchain could not be created"); - return *toolchain; - } - -private: - template - static Toolchain *AddIf(const std::string &identifier, Params &&...params) { - Toolchain *toolchain{nullptr}; - if (!Storage::Contains(identifier)) { - toolchain = - &Storage::Add(identifier, std::forward(params)...); - } - return toolchain; - } + static Toolchain & + New(ToolchainId id, const std::string &identifier, + const std::optional &op_executables = {}, + const std::optional &op_config = {}); }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_infos.h b/buildcc/toolchains/include/toolchains/toolchain_infos.h index 924b62fb..111ef2b7 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_infos.h +++ b/buildcc/toolchains/include/toolchains/toolchain_infos.h @@ -23,13 +23,27 @@ namespace buildcc { -class GlobalToolchainInfo { +class GlobalToolchainMetadata { public: - static const ToolchainInfoFunc &Get(ToolchainId id); + static const ToolchainConfig &GetConfig(ToolchainId id); + static const ToolchainInfoCb &GetInfoCb(ToolchainId id); private: - static std::unordered_map - global_toolchain_info_func_; + struct ToolchainMetadata { + ToolchainMetadata(const ToolchainConfig &config, const ToolchainInfoCb &cb) + : config_(config), cb_(cb) {} + + ToolchainConfig config_; + ToolchainInfoCb cb_; + }; + +private: + static void Expect(ToolchainId id); + static const ToolchainMetadata &Get(ToolchainId id); + +private: + static std::unordered_map + global_toolchain_metadata_; }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index 15f03932..e5685272 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -42,15 +42,15 @@ class Toolchain_mingw : public Toolchain { : Toolchain(ToolchainId::MinGW, name, op_executables.value_or( ToolchainExecutables("as", "gcc", "g++", "ar", "ld")), - op_config.value_or(ToolchainConfig())) {} + op_config.value_or(ToolchainConfig())) { + Initialize(); + } virtual ~Toolchain_mingw() = default; Toolchain_mingw(const Toolchain_mingw &) = delete; private: - void UpdateConfig(ToolchainConfig &config) override; - std::optional - GetToolchainInfo(const ToolchainExecutables &executables) const override; + void Initialize(); }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index 1cfb6252..d6fb156b 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -40,15 +40,15 @@ class Toolchain_msvc : public Toolchain { : Toolchain(ToolchainId::Msvc, name, op_executables.value_or( ToolchainExecutables("cl", "cl", "cl", "lib", "link")), - op_config.value_or(ToolchainConfig())) {} + op_config.value_or(ToolchainConfig())) { + Initialize(); + } virtual ~Toolchain_msvc() = default; - Toolchain_msvc(const Toolchain_msvc &gcc) = delete; + Toolchain_msvc(const Toolchain_msvc &) = delete; private: - void UpdateConfig(ToolchainConfig &config) override; - std::optional - GetToolchainInfo(const ToolchainExecutables &executables) const override; + void Initialize(); }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_specialized.h b/buildcc/toolchains/include/toolchains/toolchain_specialized.h new file mode 100644 index 00000000..5e316e09 --- /dev/null +++ b/buildcc/toolchains/include/toolchains/toolchain_specialized.h @@ -0,0 +1,32 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAINS_TOOLCHAIN_SPECIALIZED_H_ +#define TOOLCHAINS_TOOLCHAIN_SPECIALIZED_H_ + +// Common +#include "toolchain_infos.h" + +// Toolchain specialized implementation +#include "toolchain_gcc.h" +#include "toolchain_mingw.h" +#include "toolchain_msvc.h" + +// Aggregation +#include "toolchain_custom.h" +#include "toolchain_generic.h" + +#endif diff --git a/buildcc/toolchains/src/toolchain_aggregate.cpp b/buildcc/toolchains/src/toolchain_aggregate.cpp new file mode 100644 index 00000000..ca5fa13e --- /dev/null +++ b/buildcc/toolchains/src/toolchain_aggregate.cpp @@ -0,0 +1,86 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "toolchains/toolchain_infos.h" + +#include "toolchains/toolchain_generic.h" + +#include "toolchains/toolchain_custom.h" +#include "toolchains/toolchain_gcc.h" +#include "toolchains/toolchain_mingw.h" +#include "toolchains/toolchain_msvc.h" + +#include "env/assert_fatal.h" +#include "env/storage.h" + +namespace { + +template +static buildcc::Toolchain *AddIf(const std::string &identifier, + Params &&...params) { + buildcc::Toolchain *toolchain{nullptr}; + if (!buildcc::Storage::Contains(identifier)) { + toolchain = &buildcc::Storage::Add(identifier, + std::forward(params)...); + } + return toolchain; +} + +} // namespace + +namespace buildcc { + +void Toolchain_custom::Initialize() { + auto id = GetId(); + RefConfig() = GlobalToolchainMetadata::GetConfig(id); + SetToolchainInfoCb(GlobalToolchainMetadata::GetInfoCb(id)); +} + +Toolchain &Toolchain_generic::New( + ToolchainId id, const std::string &identifier, + const std::optional &op_executables, + const std::optional &op_config) { + Toolchain *toolchain{nullptr}; + switch (id) { + case ToolchainId::Gcc: + toolchain = + AddIf(identifier, identifier, op_executables, op_config); + break; + case ToolchainId::Msvc: + toolchain = AddIf(identifier, identifier, op_executables, + op_config); + break; + case ToolchainId::MinGW: + toolchain = AddIf(identifier, identifier, op_executables, + op_config); + break; + case ToolchainId::Clang: + case ToolchainId::Custom: + env::assert_fatal(op_executables.has_value(), + "ToolchainId::Custom and ToolchainId::Clang require " + "executables to be provided"); + toolchain = AddIf(identifier, id, identifier, + op_executables.value(), + op_config.value_or(ToolchainConfig())); + break; + default: + break; + } + env::assert_fatal(toolchain != nullptr, "Toolchain could not be created"); + return *toolchain; +} + +} // namespace buildcc diff --git a/buildcc/toolchains/src/toolchain_gcc.cpp b/buildcc/toolchains/src/toolchain_gcc.cpp index a99deef0..19b72402 100644 --- a/buildcc/toolchains/src/toolchain_gcc.cpp +++ b/buildcc/toolchains/src/toolchain_gcc.cpp @@ -21,42 +21,16 @@ #include "env/command.h" -namespace { - -constexpr const char *const kGccObjExt = ".o"; -constexpr const char *const kGccPchHeaderExt = ".h"; -constexpr const char *const kGccPchCompileExt = ".gch"; -constexpr const char *const kGccPrefixIncludeDir = "-I"; -constexpr const char *const kGccPrefixLibDir = "-L"; - -void UpdateGccConfig(buildcc::ToolchainConfig &config) { - config.obj_ext = kGccObjExt; - config.pch_header_ext = kGccPchHeaderExt; - config.pch_compile_ext = kGccPchCompileExt; - config.prefix_include_dir = kGccPrefixIncludeDir; - config.prefix_lib_dir = kGccPrefixLibDir; -} - -} // namespace - namespace buildcc { -void Toolchain_gcc::UpdateConfig(ToolchainConfig &config) { - UpdateGccConfig(config); -} - -std::optional -Toolchain_gcc::GetToolchainInfo(const ToolchainExecutables &executables) const { - return GlobalToolchainInfo::Get(ToolchainId::Gcc)(executables); -} - -void Toolchain_mingw::UpdateConfig(ToolchainConfig &config) { - UpdateGccConfig(config); +void Toolchain_gcc::Initialize() { + RefConfig() = GlobalToolchainMetadata::GetConfig(ToolchainId::Gcc); + SetToolchainInfoCb(GlobalToolchainMetadata::GetInfoCb(ToolchainId::Gcc)); } -std::optional Toolchain_mingw::GetToolchainInfo( - const ToolchainExecutables &executables) const { - return GlobalToolchainInfo::Get(ToolchainId::MinGW)(executables); +void Toolchain_mingw::Initialize() { + RefConfig() = GlobalToolchainMetadata::GetConfig(ToolchainId::MinGW); + SetToolchainInfoCb(GlobalToolchainMetadata::GetInfoCb(ToolchainId::MinGW)); } } // namespace buildcc diff --git a/buildcc/toolchains/src/toolchain_infos.cpp b/buildcc/toolchains/src/toolchain_infos.cpp index 49117e66..e17eff18 100644 --- a/buildcc/toolchains/src/toolchain_infos.cpp +++ b/buildcc/toolchains/src/toolchain_infos.cpp @@ -23,6 +23,20 @@ namespace { // GCC +constexpr const char *const kGccObjExt = ".o"; +constexpr const char *const kGccPchHeaderExt = ".h"; +constexpr const char *const kGccPchCompileExt = ".gch"; +constexpr const char *const kGccPrefixIncludeDir = "-I"; +constexpr const char *const kGccPrefixLibDir = "-L"; +buildcc::ToolchainConfig GetGccToolchainConfig() { + buildcc::ToolchainConfig config; + config.obj_ext = kGccObjExt; + config.pch_header_ext = kGccPchHeaderExt; + config.pch_compile_ext = kGccPchCompileExt; + config.prefix_include_dir = kGccPrefixIncludeDir; + config.prefix_lib_dir = kGccPrefixLibDir; + return config; +} std::optional GetGccCompilerVersion(const buildcc::env::Command &command) { @@ -65,6 +79,21 @@ GetGccToolchainInfo(const buildcc::ToolchainExecutables &executables) { // MSVC +constexpr const char *const kMsvcObjExt = ".obj"; +constexpr const char *const kMsvcPchHeaderExt = ".h"; +constexpr const char *const kMsvcPchCompileExt = ".pch"; +constexpr const char *const kMsvcPrefixIncludeDir = "/I"; +constexpr const char *const kMsvcPrefixLibDir = "/LIBPATH:"; +buildcc::ToolchainConfig GetMsvcToolchainConfig() { + buildcc::ToolchainConfig config; + config.obj_ext = kMsvcObjExt; + config.pch_header_ext = kMsvcPchHeaderExt; + config.pch_compile_ext = kMsvcPchCompileExt; + config.prefix_include_dir = kMsvcPrefixIncludeDir; + config.prefix_lib_dir = kMsvcPrefixLibDir; + return config; +} + std::optional GetMsvcCompilerVersion() { const char *vscmd_version = getenv("VSCMD_VER"); if (vscmd_version == nullptr) { @@ -108,7 +137,8 @@ GetErrorToolchainInfo(const buildcc::ToolchainExecutables &executables) { (void)executables; buildcc::env::log_critical(__FUNCTION__, "ToolchainInfo does not exist for particular " - "ToolchainId. Supply your own through 3 methods."); + "ToolchainId. Supply your own through " + "Toolchain::SetToolchainInfoCb method."); return {}; } @@ -116,23 +146,40 @@ GetErrorToolchainInfo(const buildcc::ToolchainExecutables &executables) { namespace buildcc { -// TODO, Shift this to toolchain.h -// Create a global_toolchain.h file which manages global toolchain state -std::unordered_map - GlobalToolchainInfo::global_toolchain_info_func_{ - {ToolchainId::Gcc, GetGccToolchainInfo}, - {ToolchainId::MinGW, GetGccToolchainInfo}, - {ToolchainId::Clang, GetGccToolchainInfo}, - {ToolchainId::Msvc, GetMsvcToolchainInfo}, - {ToolchainId::Custom, GetErrorToolchainInfo}, - {ToolchainId::Undefined, GetErrorToolchainInfo}, +std::unordered_map + GlobalToolchainMetadata::global_toolchain_metadata_{ + {ToolchainId::Gcc, + ToolchainMetadata(GetGccToolchainConfig(), GetGccToolchainInfo)}, + {ToolchainId::MinGW, + ToolchainMetadata(GetGccToolchainConfig(), GetGccToolchainInfo)}, + {ToolchainId::Clang, + ToolchainMetadata(GetGccToolchainConfig(), GetGccToolchainInfo)}, + {ToolchainId::Msvc, + ToolchainMetadata(GetMsvcToolchainConfig(), GetMsvcToolchainInfo)}, + {ToolchainId::Custom, + ToolchainMetadata(ToolchainConfig(), GetErrorToolchainInfo)}, + {ToolchainId::Undefined, + ToolchainMetadata(ToolchainConfig(), GetErrorToolchainInfo)}, }; -const ToolchainInfoFunc &GlobalToolchainInfo::Get(ToolchainId id) { - env::assert_fatal(global_toolchain_info_func_.find(id) != - global_toolchain_info_func_.end(), +const ToolchainConfig &GlobalToolchainMetadata::GetConfig(ToolchainId id) { + Expect(id); + return Get(id).config_; +} +const ToolchainInfoCb &GlobalToolchainMetadata::GetInfoCb(ToolchainId id) { + Expect(id); + return Get(id).cb_; +} + +// PRIVATE +void GlobalToolchainMetadata::Expect(ToolchainId id) { + env::assert_fatal(global_toolchain_metadata_.find(id) != + global_toolchain_metadata_.end(), "Invalid ToolchainId"); - return global_toolchain_info_func_[id]; +} +const GlobalToolchainMetadata::ToolchainMetadata & +GlobalToolchainMetadata::Get(ToolchainId id) { + return global_toolchain_metadata_.at(id); } } // namespace buildcc diff --git a/buildcc/toolchains/src/toolchain_msvc.cpp b/buildcc/toolchains/src/toolchain_msvc.cpp index a6eca961..ddb047e6 100644 --- a/buildcc/toolchains/src/toolchain_msvc.cpp +++ b/buildcc/toolchains/src/toolchain_msvc.cpp @@ -18,29 +18,11 @@ #include "toolchains/toolchain_infos.h" -namespace { - -constexpr const char *const kMsvcObjExt = ".obj"; -constexpr const char *const kMsvcPchHeaderExt = ".h"; -constexpr const char *const kMsvcPchCompileExt = ".pch"; -constexpr const char *const kMsvcPrefixIncludeDir = "/I"; -constexpr const char *const kMsvcPrefixLibDir = "/LIBPATH:"; - -} // namespace - namespace buildcc { -void Toolchain_msvc::UpdateConfig(ToolchainConfig &config) { - config.obj_ext = kMsvcObjExt; - config.pch_header_ext = kMsvcPchHeaderExt; - config.pch_compile_ext = kMsvcPchCompileExt; - config.prefix_include_dir = kMsvcPrefixIncludeDir; - config.prefix_lib_dir = kMsvcPrefixLibDir; -} - -std::optional Toolchain_msvc::GetToolchainInfo( - const ToolchainExecutables &executables) const { - return GlobalToolchainInfo::Get(ToolchainId::Msvc)(executables); +void Toolchain_msvc::Initialize() { + RefConfig() = GlobalToolchainMetadata::GetConfig(ToolchainId::Msvc); + SetToolchainInfoCb(GlobalToolchainMetadata::GetInfoCb(ToolchainId::Msvc)); } } // namespace buildcc diff --git a/buildcc/toolchains/test/test_toolchain_specialized.cpp b/buildcc/toolchains/test/test_toolchain_specialized.cpp new file mode 100644 index 00000000..f6d47256 --- /dev/null +++ b/buildcc/toolchains/test/test_toolchain_specialized.cpp @@ -0,0 +1,383 @@ +#include "env/host_os_util.h" +#include "env/storage.h" +#include "env/util.h" + +#include "expect_command.h" +#include "mock_command_copier.h" + +#include "toolchains/toolchain_specialized.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(ToolchainSpecializedTestGroup) +{ + void setup() { + } + void teardown() { + mock().clear(); + } +}; +// clang-format on + +TEST(ToolchainSpecializedTestGroup, GCC) { + buildcc::Toolchain_gcc gcc; + STRCMP_EQUAL(gcc.GetName().c_str(), "gcc"); + STRCMP_EQUAL(gcc.GetAssembler().c_str(), "as"); + STRCMP_EQUAL(gcc.GetCCompiler().c_str(), "gcc"); + STRCMP_EQUAL(gcc.GetCppCompiler().c_str(), "g++"); + STRCMP_EQUAL(gcc.GetArchiver().c_str(), "ar"); + STRCMP_EQUAL(gcc.GetLinker().c_str(), "ld"); + + fs::path current_directory = fs::current_path(); + buildcc::ToolchainFindConfig find_config; + find_config.env_vars.clear(); + find_config.absolute_search_paths.insert(current_directory); + + std::vector version_stdout{"version"}; + std::vector arch_stdout{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout); + auto info = gcc.Verify(find_config); + STRCMP_EQUAL(info.compiler_version.c_str(), "version"); + STRCMP_EQUAL(info.target_arch.c_str(), "arch"); +} + +TEST(ToolchainSpecializedTestGroup, GCC_Fail) { + buildcc::Toolchain_gcc gcc; + STRCMP_EQUAL(gcc.GetName().c_str(), "gcc"); + STRCMP_EQUAL(gcc.GetAssembler().c_str(), "as"); + STRCMP_EQUAL(gcc.GetCCompiler().c_str(), "gcc"); + STRCMP_EQUAL(gcc.GetCppCompiler().c_str(), "g++"); + STRCMP_EQUAL(gcc.GetArchiver().c_str(), "ar"); + STRCMP_EQUAL(gcc.GetLinker().c_str(), "ld"); + + fs::path current_directory = fs::current_path(); + buildcc::ToolchainFindConfig find_config; + find_config.env_vars.clear(); + find_config.absolute_search_paths.insert(current_directory); + + { + std::vector version_stdout{"version"}; + std::vector arch_stdout{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, false, &version_stdout); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout); + CHECK_THROWS(std::exception, gcc.Verify(find_config)); + } + + { + std::vector version_stdout; + std::vector arch_stdout{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout); + CHECK_THROWS(std::exception, gcc.Verify(find_config)); + } + + { + std::vector version_stdout{"version"}; + std::vector arch_stdout{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout); + buildcc::env::m::CommandExpect_Execute(1, false, &arch_stdout); + CHECK_THROWS(std::exception, gcc.Verify(find_config)); + } + + { + std::vector version_stdout{"version"}; + std::vector arch_stdout{}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout); + CHECK_THROWS(std::exception, gcc.Verify(find_config)); + } +} + +TEST(ToolchainSpecializedTestGroup, MINGW) { + buildcc::Toolchain_mingw gcc; + STRCMP_EQUAL(gcc.GetName().c_str(), "gcc"); + STRCMP_EQUAL(gcc.GetAssembler().c_str(), "as"); + STRCMP_EQUAL(gcc.GetCCompiler().c_str(), "gcc"); + STRCMP_EQUAL(gcc.GetCppCompiler().c_str(), "g++"); + STRCMP_EQUAL(gcc.GetArchiver().c_str(), "ar"); + STRCMP_EQUAL(gcc.GetLinker().c_str(), "ld"); + + fs::path current_directory = fs::current_path(); + buildcc::ToolchainFindConfig find_config; + find_config.env_vars.clear(); + find_config.absolute_search_paths.insert(current_directory); + + std::vector version_stdout{"version"}; + std::vector arch_stdout{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout); + auto info = gcc.Verify(find_config); + STRCMP_EQUAL(info.compiler_version.c_str(), "version"); + STRCMP_EQUAL(info.target_arch.c_str(), "arch"); +} + +#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__MINGW64__) + +TEST(ToolchainSpecializedTestGroup, MSVC) { + buildcc::Toolchain_msvc msvc; + STRCMP_EQUAL(msvc.GetName().c_str(), "msvc"); + STRCMP_EQUAL(msvc.GetAssembler().c_str(), "cl"); + STRCMP_EQUAL(msvc.GetCCompiler().c_str(), "cl"); + STRCMP_EQUAL(msvc.GetCppCompiler().c_str(), "cl"); + STRCMP_EQUAL(msvc.GetArchiver().c_str(), "lib"); + STRCMP_EQUAL(msvc.GetLinker().c_str(), "link"); + + const auto &toolchain_config = msvc.GetConfig(); + STRCMP_EQUAL(toolchain_config.obj_ext.c_str(), ".obj"); + STRCMP_EQUAL(toolchain_config.pch_header_ext.c_str(), ".h"); + STRCMP_EQUAL(toolchain_config.pch_compile_ext.c_str(), ".pch"); + STRCMP_EQUAL(toolchain_config.prefix_include_dir.c_str(), "/I"); + STRCMP_EQUAL(toolchain_config.prefix_lib_dir.c_str(), "/LIBPATH:"); + + fs::path current_directory = fs::current_path(); + buildcc::ToolchainFindConfig find_config; + find_config.env_vars.clear(); + find_config.absolute_search_paths.insert(current_directory); + + char vscmd_ver[] = "VSCMD_VER=version"; + char vscmd_arg_host_arch[] = "VSCMD_ARG_HOST_ARCH=host"; + char vscmd_arg_tgt_arch[] = "VSCMD_ARG_TGT_ARCH=target"; + CHECK_EQUAL(putenv(vscmd_ver), 0); + CHECK_EQUAL(putenv(vscmd_arg_host_arch), 0); + CHECK_EQUAL(putenv(vscmd_arg_tgt_arch), 0); + auto info = msvc.Verify(find_config); + STRCMP_EQUAL(info.compiler_version.c_str(), "version"); + STRCMP_EQUAL(info.target_arch.c_str(), "host_target"); +} + +TEST(ToolchainSpecializedTestGroup, MSVC_Fail) { + buildcc::Toolchain_msvc msvc; + STRCMP_EQUAL(msvc.GetName().c_str(), "msvc"); + STRCMP_EQUAL(msvc.GetAssembler().c_str(), "cl"); + STRCMP_EQUAL(msvc.GetCCompiler().c_str(), "cl"); + STRCMP_EQUAL(msvc.GetCppCompiler().c_str(), "cl"); + STRCMP_EQUAL(msvc.GetArchiver().c_str(), "lib"); + STRCMP_EQUAL(msvc.GetLinker().c_str(), "link"); + + const auto &toolchain_config = msvc.GetConfig(); + STRCMP_EQUAL(toolchain_config.obj_ext.c_str(), ".obj"); + STRCMP_EQUAL(toolchain_config.pch_header_ext.c_str(), ".h"); + STRCMP_EQUAL(toolchain_config.pch_compile_ext.c_str(), ".pch"); + STRCMP_EQUAL(toolchain_config.prefix_include_dir.c_str(), "/I"); + STRCMP_EQUAL(toolchain_config.prefix_lib_dir.c_str(), "/LIBPATH:"); + + fs::path current_directory = fs::current_path(); + buildcc::ToolchainFindConfig find_config; + find_config.env_vars.clear(); + find_config.absolute_search_paths.insert(current_directory); + + { + char vscmd_ver[] = "VSCMD_VER"; + char vscmd_arg_host_arch[] = "VSCMD_ARG_HOST_ARCH"; + char vscmd_arg_tgt_arch[] = "VSCMD_ARG_TGT_ARCH"; + CHECK_EQUAL(putenv(vscmd_ver), 0); + CHECK_EQUAL(putenv(vscmd_arg_host_arch), 0); + CHECK_EQUAL(putenv(vscmd_arg_tgt_arch), 0); + CHECK_THROWS(std::exception, msvc.Verify(find_config)); + } + + { + char vscmd_ver[] = "VSCMD_VER"; + char vscmd_arg_host_arch[] = "VSCMD_ARG_HOST_ARCH=host"; + char vscmd_arg_tgt_arch[] = "VSCMD_ARG_TGT_ARCH"; + CHECK_EQUAL(putenv(vscmd_ver), 0); + CHECK_EQUAL(putenv(vscmd_arg_host_arch), 0); + CHECK_EQUAL(putenv(vscmd_arg_tgt_arch), 0); + CHECK_THROWS(std::exception, msvc.Verify(find_config)); + } + + { + char vscmd_ver[] = "VSCMD_VER"; + char vscmd_arg_host_arch[] = "VSCMD_ARG_HOST_ARCH"; + char vscmd_arg_tgt_arch[] = "VSCMD_ARG_TGT_ARCH=target"; + CHECK_EQUAL(putenv(vscmd_ver), 0); + CHECK_EQUAL(putenv(vscmd_arg_host_arch), 0); + CHECK_EQUAL(putenv(vscmd_arg_tgt_arch), 0); + CHECK_THROWS(std::exception, msvc.Verify(find_config)); + } + + { + char vscmd_ver[] = "VSCMD_VER=version"; + char vscmd_arg_host_arch[] = "VSCMD_ARG_HOST_ARCH"; + char vscmd_arg_tgt_arch[] = "VSCMD_ARG_TGT_ARCH"; + CHECK_EQUAL(putenv(vscmd_ver), 0); + CHECK_EQUAL(putenv(vscmd_arg_host_arch), 0); + CHECK_EQUAL(putenv(vscmd_arg_tgt_arch), 0); + CHECK_THROWS(std::exception, msvc.Verify(find_config)); + } +} + +#endif + +TEST(ToolchainSpecializedTestGroup, Clang) { + buildcc::Toolchain_custom clang( + buildcc::ToolchainId::Clang, "clang", + buildcc::ToolchainExecutables("llvm-as", "clang", "clang++", "llvm-ar", + "ld")); + STRCMP_EQUAL(clang.GetName().c_str(), "clang"); + STRCMP_EQUAL(clang.GetAssembler().c_str(), "llvm-as"); + STRCMP_EQUAL(clang.GetCCompiler().c_str(), "clang"); + STRCMP_EQUAL(clang.GetCppCompiler().c_str(), "clang++"); + STRCMP_EQUAL(clang.GetArchiver().c_str(), "llvm-ar"); + STRCMP_EQUAL(clang.GetLinker().c_str(), "ld"); + + fs::path current_directory = fs::current_path(); + buildcc::ToolchainFindConfig find_config; + find_config.env_vars.clear(); + find_config.absolute_search_paths.insert(current_directory); + + std::vector version_stdout{"version"}; + std::vector arch_stdout{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout); + auto info = clang.Verify(find_config); + STRCMP_EQUAL(info.compiler_version.c_str(), "version"); + STRCMP_EQUAL(info.target_arch.c_str(), "arch"); +} + +TEST(ToolchainSpecializedTestGroup, Global) { + CHECK_THROWS(std::exception, buildcc::GlobalToolchainMetadata::GetConfig( + (buildcc::ToolchainId)65535)); + + CHECK_THROWS(std::exception, buildcc::GlobalToolchainMetadata::GetInfoCb( + (buildcc::ToolchainId)65535)); + + CHECK_FALSE(buildcc::GlobalToolchainMetadata::GetInfoCb( + buildcc::ToolchainId::Custom)(buildcc::ToolchainExecutables()) + .has_value()); + CHECK_FALSE( + buildcc::GlobalToolchainMetadata::GetInfoCb( + buildcc::ToolchainId::Undefined)(buildcc::ToolchainExecutables()) + .has_value()); +} + +TEST(ToolchainSpecializedTestGroup, Generic) { + MemoryLeakWarningPlugin::saveAndDisableNewDeleteOverloads(); + + { + auto &gcc = + buildcc::Toolchain_generic::New(buildcc::ToolchainId::Gcc, "gcc"); + STRCMP_EQUAL(gcc.GetName().c_str(), "gcc"); + STRCMP_EQUAL(gcc.GetAssembler().c_str(), "as"); + STRCMP_EQUAL(gcc.GetCCompiler().c_str(), "gcc"); + STRCMP_EQUAL(gcc.GetCppCompiler().c_str(), "g++"); + STRCMP_EQUAL(gcc.GetArchiver().c_str(), "ar"); + STRCMP_EQUAL(gcc.GetLinker().c_str(), "ld"); + + // Already defined with same identifier + CHECK_THROWS(std::exception, buildcc::Toolchain_generic::New( + buildcc::ToolchainId::Gcc, "gcc")); + } + + { + auto &mingw = + buildcc::Toolchain_generic::New(buildcc::ToolchainId::MinGW, "mingw"); + STRCMP_EQUAL(mingw.GetName().c_str(), "mingw"); + STRCMP_EQUAL(mingw.GetAssembler().c_str(), "as"); + STRCMP_EQUAL(mingw.GetCCompiler().c_str(), "gcc"); + STRCMP_EQUAL(mingw.GetCppCompiler().c_str(), "g++"); + STRCMP_EQUAL(mingw.GetArchiver().c_str(), "ar"); + STRCMP_EQUAL(mingw.GetLinker().c_str(), "ld"); + } + + { + auto &msvc = + buildcc::Toolchain_generic::New(buildcc::ToolchainId::Msvc, "msvc"); + STRCMP_EQUAL(msvc.GetName().c_str(), "msvc"); + STRCMP_EQUAL(msvc.GetAssembler().c_str(), "cl"); + STRCMP_EQUAL(msvc.GetCCompiler().c_str(), "cl"); + STRCMP_EQUAL(msvc.GetCppCompiler().c_str(), "cl"); + STRCMP_EQUAL(msvc.GetArchiver().c_str(), "lib"); + STRCMP_EQUAL(msvc.GetLinker().c_str(), "link"); + + const auto &toolchain_config = msvc.GetConfig(); + STRCMP_EQUAL(toolchain_config.obj_ext.c_str(), ".obj"); + STRCMP_EQUAL(toolchain_config.pch_header_ext.c_str(), ".h"); + STRCMP_EQUAL(toolchain_config.pch_compile_ext.c_str(), ".pch"); + STRCMP_EQUAL(toolchain_config.prefix_include_dir.c_str(), "/I"); + STRCMP_EQUAL(toolchain_config.prefix_lib_dir.c_str(), "/LIBPATH:"); + } + + { + auto &clang = buildcc::Toolchain_generic::New( + buildcc::ToolchainId::Clang, "clang", + buildcc::ToolchainExecutables("llvm-as", "clang", "clang++", "llvm-ar", + "ld")); + STRCMP_EQUAL(clang.GetName().c_str(), "clang"); + STRCMP_EQUAL(clang.GetAssembler().c_str(), "llvm-as"); + STRCMP_EQUAL(clang.GetCCompiler().c_str(), "clang"); + STRCMP_EQUAL(clang.GetCppCompiler().c_str(), "clang++"); + STRCMP_EQUAL(clang.GetArchiver().c_str(), "llvm-ar"); + STRCMP_EQUAL(clang.GetLinker().c_str(), "ld"); + } + + { + CHECK_THROWS(std::exception, buildcc::Toolchain_generic::New( + buildcc::ToolchainId::Custom, "custom")); + } + + { + CHECK_THROWS(std::exception, + buildcc::Toolchain_generic::New( + buildcc::ToolchainId::Undefined, "undefined")); + } + + buildcc::Storage::Clear(); + MemoryLeakWarningPlugin::restoreNewDeleteOverloads(); +} + +// + +void convert_executables_to_full_path(buildcc::ToolchainExecutables &exes, + const std::string &ext) { + fs::path current_path = fs::current_path().make_preferred(); + exes.assembler = + (current_path / fmt::format("{}{}", exes.assembler, ext)).string(); + exes.c_compiler = + (current_path / fmt::format("{}{}", exes.c_compiler, ext)).string(); + exes.cpp_compiler = + (current_path / fmt::format("{}{}", exes.cpp_compiler, ext)).string(); + exes.archiver = + (current_path / fmt::format("{}{}", exes.archiver, ext)).string(); + exes.linker = (current_path / fmt::format("{}{}", exes.linker, ext)).string(); +} + +void create_dummy_executables(const buildcc::ToolchainExecutables &exes) { + buildcc::env::save_file(exes.assembler.c_str(), "", false); + buildcc::env::save_file(exes.c_compiler.c_str(), "", false); + buildcc::env::save_file(exes.cpp_compiler.c_str(), "", false); + buildcc::env::save_file(exes.archiver.c_str(), "", false); + buildcc::env::save_file(exes.linker.c_str(), "", false); +} + +int main(int ac, char **av) { + buildcc::env::m::VectorStringCopier copier; + mock().installCopier(TEST_VECTOR_STRING_TYPE, copier); + + constexpr const char *const exe_ext = + buildcc::env::get_os_executable_extension(); + std::string ext = ""; + if (exe_ext) { + ext = exe_ext; + } + buildcc::ToolchainExecutables gcc_exes("as", "gcc", "g++", "ar", "ld"); + convert_executables_to_full_path(gcc_exes, ext); + create_dummy_executables(gcc_exes); + + buildcc::ToolchainExecutables msvc_exes("cl", "cl", "cl", "lib", "link"); + convert_executables_to_full_path(msvc_exes, ext); + create_dummy_executables(msvc_exes); + + buildcc::ToolchainExecutables clang_exes("llvm-as", "clang", "clang++", + "llvm-ar", "ld"); + convert_executables_to_full_path(clang_exes, ext); + create_dummy_executables(clang_exes); + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildexe/buildexe.cpp b/buildexe/buildexe.cpp index 31715ec9..08926b0a 100644 --- a/buildexe/buildexe.cpp +++ b/buildexe/buildexe.cpp @@ -57,8 +57,7 @@ int main(int argc, char **argv) { Reg::Call(Args::Clean()).Func(clean_cb); // Host Toolchain - auto &toolchain = buildexe_args.GetHostToolchainArg(); - toolchain.SetToolchainInfoFunc(GlobalToolchainInfo::Get(toolchain.id)); + auto &toolchain = buildexe_args.GetHostToolchainArg().ConstructToolchain(); toolchain.Verify(); if (buildexe_args.GetBuildMode() == BuildExeMode::Script) { diff --git a/docs/source/user_api/args.rst b/docs/source/user_api/args.rst index 6f7e027a..5c7bbd72 100644 --- a/docs/source/user_api/args.rst +++ b/docs/source/user_api/args.rst @@ -10,7 +10,7 @@ args.h .. doxygenstruct:: buildcc::ArgToolchainState -.. doxygenstruct:: buildcc::ArgToolchain +.. doxygenclass:: buildcc::ArgToolchain .. doxygenstruct:: buildcc::ArgTarget diff --git a/docs/source/user_api/toolchain.rst b/docs/source/user_api/toolchain.rst index 19e6bb8a..5bdc1114 100644 --- a/docs/source/user_api/toolchain.rst +++ b/docs/source/user_api/toolchain.rst @@ -20,8 +20,6 @@ toolchain_verify.h .. doxygenclass:: buildcc::ToolchainVerify -.. doxygenstruct:: buildcc::ToolchainVerifyConfig - .. doxygenstruct:: buildcc::ToolchainCompilerInfo Example for Default Toolchain diff --git a/example/hybrid/custom_target/build.main.cpp b/example/hybrid/custom_target/build.main.cpp index 82b03727..88ece332 100644 --- a/example/hybrid/custom_target/build.main.cpp +++ b/example/hybrid/custom_target/build.main.cpp @@ -36,11 +36,11 @@ int main(int argc, char **argv) { Reg::Toolchain(arg_msvc.state).Build(foolib_build_cb, m_foolib); // * NOTE, This is how we add our custom toolchain - auto &clang = arg_toolchain_clang_gnu; - clang.SetToolchainInfoFunc(GlobalToolchainInfo::Get(clang.id)); + auto &clang = arg_toolchain_clang_gnu.ConstructToolchain(); Target_custom c_foolib("CFoolib.exe", TargetType::Executable, clang, "", arg_target_clang_gnu.GetTargetConfig()); - Reg::Toolchain(clang.state).Build(foolib_build_cb, c_foolib); + Reg::Toolchain(arg_toolchain_clang_gnu.state) + .Build(foolib_build_cb, c_foolib); // Reg::Run(); diff --git a/example/hybrid/generic/build.cpp b/example/hybrid/generic/build.cpp index a6c28d0d..fd388c36 100644 --- a/example/hybrid/generic/build.cpp +++ b/example/hybrid/generic/build.cpp @@ -41,8 +41,7 @@ int main(int argc, char **argv) { // Build steps // Toolchain + Generic Target - auto &toolchain = custom_toolchain; - toolchain.SetToolchainInfoFunc(GlobalToolchainInfo::Get(toolchain.id)); + auto &toolchain = custom_toolchain.ConstructToolchain(); Target_generic foolib_target("libfoo", default_lib_type, toolchain, "../foolib"); Target_generic generic_target("generic", TargetType::Executable, toolchain, From afff3dd2e359c0d2300f749300dfebb63dbe305a Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 30 Apr 2022 07:04:53 -0700 Subject: [PATCH 18/35] Compilation speedup (#211) --- README.md | 6 +-- buildcc/CMakeLists.txt | 8 ++-- buildcc/lib/args/test/test_register.cpp | 40 +++++++++++------- buildcc/lib/env/CMakeLists.txt | 6 +-- buildcc/lib/env/include/env/storage.h | 4 +- .../target/test/target/test_base_target.cpp | 5 ++- .../test/target/test_compile_object.cpp | 5 ++- .../test/target/test_target_external_lib.cpp | 5 ++- .../target/test_target_failure_states.cpp | 5 ++- .../target/test/target/test_target_flags.cpp | 5 ++- .../test/target/test_target_include_dir.cpp | 5 ++- .../test/target/test_target_lib_dep.cpp | 5 ++- .../target/test/target/test_target_lock.cpp | 5 ++- .../target/test/target/test_target_pch.cpp | 5 ++- .../target/test/target/test_target_source.cpp | 5 ++- .../target/test_target_source_out_of_root.cpp | 5 ++- .../target/test/target/test_target_sync.cpp | 5 ++- .../test/target/test_target_user_deps.cpp | 5 ++- .../test/target/test_toolchain_flag_api.cpp | 15 ++++--- .../toolchain/include/toolchain/toolchain.h | 11 ----- .../toolchain/test/test_toolchain_find.cpp | 25 ++++++----- .../plugins/include/plugins/buildcc_find.h | 1 + buildcc/schema/cmake/schema.cmake | 4 +- cmake/target/flatbuffers.cmake | 23 +--------- .../buildcc_interface_lib.PNG | Bin 144370 -> 151647 bytes .../buildcc_single_lib.PNG | Bin 132243 -> 120571 bytes docs/source/arch/cmake_boilerplate.rst | 6 +-- docs/source/examples/gcc.rst | 4 +- example/gcc/AfterInstall/CMakeLists.txt | 4 +- 29 files changed, 109 insertions(+), 113 deletions(-) diff --git a/README.md b/README.md index f6f5bf57..038af93f 100644 --- a/README.md +++ b/README.md @@ -170,11 +170,11 @@ _BuildCC_ is licensed under the Apache License, Version 2.0. See [LICENSE](LICEN > Developers who would like to suggest an alternative library, raise an issue with the **license** and **advantages** clearly outlined. -- [Fmtlib](https://github.com/fmtlib/fmt) (Formatting) [MIT License] [Header Only] -- [Spdlog](https://github.com/gabime/spdlog) (Logging) [MIT License] [Header Only] +- [Fmtlib](https://github.com/fmtlib/fmt) (Formatting) [MIT License] +- [Spdlog](https://github.com/gabime/spdlog) (Logging) [MIT License] - [Tiny Process Library](https://gitlab.com/eidheim/tiny-process-library) (Process handling) [MIT License] - [Taskflow](https://github.com/taskflow/taskflow) (Parallel Programming) [MIT License] [Header Only] - See also [3rd-Party](https://github.com/taskflow/taskflow/tree/master/3rd-party) used by Taskflow -- [Flatbuffers](https://github.com/google/flatbuffers) (Serialization) [Apache-2.0 License] [Header Only] +- [Flatbuffers](https://github.com/google/flatbuffers) (Serialization) [Apache-2.0 License] - [CLI11](https://github.com/CLIUtils/CLI11) (Argument Parsing) [BSD-3-Clause License] [Header Only] - [CppUTest](https://github.com/cpputest/cpputest) (Unit Testing/Mocking) [BSD-3-Clause License] diff --git a/buildcc/CMakeLists.txt b/buildcc/CMakeLists.txt index f4d5d628..035da54b 100644 --- a/buildcc/CMakeLists.txt +++ b/buildcc/CMakeLists.txt @@ -11,20 +11,19 @@ if(${BUILDCC_BUILD_AS_SINGLE_LIB}) $ ) target_link_libraries(buildcc PUBLIC - fmt::fmt-header-only - flatbuffers_header_only + fmt::fmt + flatbuffers Taskflow CLI11::CLI11 ) target_link_libraries(buildcc PRIVATE - spdlog::spdlog_header_only + spdlog::spdlog tiny-process-library::tiny-process-library ) target_compile_options(buildcc PRIVATE ${BUILD_COMPILE_FLAGS}) target_link_options(buildcc PRIVATE ${BUILD_LINK_FLAGS}) if(${BUILDCC_PRECOMPILE_HEADERS}) target_precompile_headers(buildcc INTERFACE buildcc.h) - target_precompile_headers(buildcc INTERFACE ${FBS_DIR}/pch/pch.h) endif() endif() @@ -65,7 +64,6 @@ if (${BUILDCC_BUILD_AS_INTERFACE}) ) if(${BUILDCC_PRECOMPILE_HEADERS}) target_precompile_headers(buildcc_i INTERFACE buildcc.h) - target_precompile_headers(buildcc_i INTERFACE ${FBS_DIR}/pch/pch.h) endif() endif() diff --git a/buildcc/lib/args/test/test_register.cpp b/buildcc/lib/args/test/test_register.cpp index 2403876c..04d8661e 100644 --- a/buildcc/lib/args/test/test_register.cpp +++ b/buildcc/lib/args/test/test_register.cpp @@ -108,8 +108,9 @@ TEST(RegisterTestGroup, Register_Build) { // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", - ""); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "", + buildcc::ToolchainExecutables("", "", "", "", "")); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); @@ -160,8 +161,9 @@ TEST(RegisterTestGroup, Register_Run_PostCb) { // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", - ""); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "", + buildcc::ToolchainExecutables("", "", "", "", "")); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); @@ -203,8 +205,9 @@ TEST(RegisterTestGroup, Register_NoBuildAndDep) { // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", - ""); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "", + buildcc::ToolchainExecutables("", "", "", "", "")); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); buildcc::BaseTarget dependency("depT", buildcc::TargetType::Executable, @@ -292,8 +295,9 @@ TEST(RegisterTestGroup, Register_BuildAndDep) { // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", - ""); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "", + buildcc::ToolchainExecutables("", "", "", "", "")); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); buildcc::BaseTarget dependency("depT", buildcc::TargetType::Executable, @@ -389,8 +393,9 @@ TEST(RegisterTestGroup, Register_DepDuplicate) { // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", - ""); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "", + buildcc::ToolchainExecutables("", "", "", "", "")); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); buildcc::BaseTarget dependency("depT", buildcc::TargetType::Executable, @@ -465,8 +470,9 @@ TEST(RegisterTestGroup, Register_DepCyclic) { // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", - ""); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "", + buildcc::ToolchainExecutables("", "", "", "", "")); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); buildcc::BaseTarget dependency("depT", buildcc::TargetType::Executable, @@ -542,8 +548,9 @@ TEST(RegisterTestGroup, Register_Test) { // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", - ""); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "", + buildcc::ToolchainExecutables("", "", "", "", "")); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); buildcc::BaseTarget dependency("depT", buildcc::TargetType::Executable, @@ -632,8 +639,9 @@ TEST(RegisterTestGroup, Register_TestWithOutput) { // Make dummy toolchain and target buildcc::Project::Init(fs::current_path(), fs::current_path()); - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "", "", "", "", "", - ""); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "", + buildcc::ToolchainExecutables("", "", "", "", "")); buildcc::BaseTarget target("dummyT", buildcc::TargetType::Executable, toolchain, ""); buildcc::BaseTarget dependency("depT", buildcc::TargetType::Executable, diff --git a/buildcc/lib/env/CMakeLists.txt b/buildcc/lib/env/CMakeLists.txt index 8af914c2..1cc6c285 100644 --- a/buildcc/lib/env/CMakeLists.txt +++ b/buildcc/lib/env/CMakeLists.txt @@ -16,7 +16,7 @@ if (${TESTING}) ${CMAKE_CURRENT_SOURCE_DIR}/mock/include ) target_link_libraries(mock_env PUBLIC - fmt::fmt-header-only + fmt::fmt Taskflow CppUTest @@ -96,11 +96,11 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) $ $ ) - target_link_libraries(env PUBLIC fmt::fmt-header-only) + target_link_libraries(env PUBLIC fmt::fmt) target_compile_options(env PRIVATE ${BUILD_COMPILE_FLAGS}) target_link_options(env PRIVATE ${BUILD_LINK_FLAGS}) target_link_libraries(env PRIVATE - spdlog::spdlog_header_only + spdlog::spdlog tiny-process-library::tiny-process-library ) endif() diff --git a/buildcc/lib/env/include/env/storage.h b/buildcc/lib/env/include/env/storage.h index 21d5528e..b5407df8 100644 --- a/buildcc/lib/env/include/env/storage.h +++ b/buildcc/lib/env/include/env/storage.h @@ -100,10 +100,10 @@ class ScopedStorage { * @param ptr Can hold data of any type * @param typeid_name We cannot store a template type so this is the next * best thing - * @param desstructor Destructor callback to delete ptr + * @param destructor Destructor callback to delete ptr */ struct PtrMetadata { - void *ptr; + void *ptr{nullptr}; std::string typeid_name; std::function destructor; }; diff --git a/buildcc/lib/target/test/target/test_base_target.cpp b/buildcc/lib/target/test/target/test_base_target.cpp index ddc4990d..a00c5a24 100644 --- a/buildcc/lib/target/test/target/test_base_target.cpp +++ b/buildcc/lib/target/test/target/test_base_target.cpp @@ -21,8 +21,9 @@ TEST_GROUP(TargetBaseTestGroup) } }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); TEST(TargetBaseTestGroup, InvalidTargetType) { constexpr const char *const INVALID_NAME = "Invalid.random"; diff --git a/buildcc/lib/target/test/target/test_compile_object.cpp b/buildcc/lib/target/test/target/test_compile_object.cpp index 8c5f1f8e..d3cdcdff 100644 --- a/buildcc/lib/target/test/target/test_compile_object.cpp +++ b/buildcc/lib/target/test/target/test_compile_object.cpp @@ -15,8 +15,9 @@ TEST_GROUP(TargetCompileObjectTestGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); TEST(TargetCompileObjectTestGroup, CacheCompileCommand_Invalid) { buildcc::BaseTarget target("CacheCompileCommand_Invalid", diff --git a/buildcc/lib/target/test/target/test_target_external_lib.cpp b/buildcc/lib/target/test/target/test_target_external_lib.cpp index 4a979b6d..404f7330 100644 --- a/buildcc/lib/target/test/target/test_target_external_lib.cpp +++ b/buildcc/lib/target/test/target/test_target_external_lib.cpp @@ -27,8 +27,9 @@ TEST_GROUP(TargetTestExternalLib) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); static const fs::path intermediate_path = fs::path(BUILD_TARGET_EXTERNAL_LIB_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_failure_states.cpp b/buildcc/lib/target/test/target/test_target_failure_states.cpp index 61ea9176..f7d813f5 100644 --- a/buildcc/lib/target/test/target/test_target_failure_states.cpp +++ b/buildcc/lib/target/test/target/test_target_failure_states.cpp @@ -25,8 +25,9 @@ TEST_GROUP(TargetTestFailureStates) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); TEST(TargetTestFailureStates, StartTaskEnvFailure) { buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE); diff --git a/buildcc/lib/target/test/target/test_target_flags.cpp b/buildcc/lib/target/test/target/test_target_flags.cpp index cfef234f..72933547 100644 --- a/buildcc/lib/target/test/target/test_target_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_flags.cpp @@ -21,8 +21,9 @@ // Constants -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); // ------------- PREPROCESSOR FLAGS --------------- diff --git a/buildcc/lib/target/test/target/test_target_include_dir.cpp b/buildcc/lib/target/test/target/test_target_include_dir.cpp index 5f95c603..ea8633b0 100644 --- a/buildcc/lib/target/test/target/test_target_include_dir.cpp +++ b/buildcc/lib/target/test/target/test_target_include_dir.cpp @@ -26,8 +26,9 @@ TEST_GROUP(TargetTestIncludeDirGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); static const fs::path target_include_dir_intermediate_path = fs::path(BUILD_TARGET_INCLUDE_DIR_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_lib_dep.cpp b/buildcc/lib/target/test/target/test_target_lib_dep.cpp index 56c97666..2f83d5b2 100644 --- a/buildcc/lib/target/test/target/test_target_lib_dep.cpp +++ b/buildcc/lib/target/test/target/test_target_lib_dep.cpp @@ -30,8 +30,9 @@ TEST_GROUP(TargetTestLibDep) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); static const fs::path intermediate_path = fs::path(BUILD_TARGET_LIB_DEP_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_lock.cpp b/buildcc/lib/target/test/target/test_target_lock.cpp index 768db823..b3b3f5f9 100644 --- a/buildcc/lib/target/test/target/test_target_lock.cpp +++ b/buildcc/lib/target/test/target/test_target_lock.cpp @@ -25,8 +25,9 @@ TEST_GROUP(TargetTestLock) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); TEST(TargetTestLock, LockState) { constexpr const char *const NAME = "LockState.exe"; diff --git a/buildcc/lib/target/test/target/test_target_pch.cpp b/buildcc/lib/target/test/target/test_target_pch.cpp index 8eefcba2..4278c40c 100644 --- a/buildcc/lib/target/test/target/test_target_pch.cpp +++ b/buildcc/lib/target/test/target/test_target_pch.cpp @@ -30,8 +30,9 @@ TEST_GROUP(TargetPchTestGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); TEST(TargetPchTestGroup, Target_AddPch) { constexpr const char *const NAME = "AddPch.exe"; diff --git a/buildcc/lib/target/test/target/test_target_source.cpp b/buildcc/lib/target/test/target/test_target_source.cpp index b94c2dfb..2d09ab04 100644 --- a/buildcc/lib/target/test/target/test_target_source.cpp +++ b/buildcc/lib/target/test/target/test_target_source.cpp @@ -27,8 +27,9 @@ TEST_GROUP(TargetTestSourceGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); static const fs::path target_source_intermediate_path = fs::path(BUILD_TARGET_SOURCE_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp b/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp index b4fcac9a..5381f659 100644 --- a/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp +++ b/buildcc/lib/target/test/target/test_target_source_out_of_root.cpp @@ -26,8 +26,9 @@ TEST_GROUP(TargetTestSourceOutOfRootGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); static const fs::path target_source_intermediate_path = fs::path(BUILD_TARGET_SOURCE_OUT_OF_ROOT_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_sync.cpp b/buildcc/lib/target/test/target/test_target_sync.cpp index 8380e318..50e7f207 100644 --- a/buildcc/lib/target/test/target/test_target_sync.cpp +++ b/buildcc/lib/target/test/target/test_target_sync.cpp @@ -19,8 +19,9 @@ TEST_GROUP(TargetTestSyncGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ldd"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); TEST(TargetTestSyncGroup, CopyByConstRef) { buildcc::BaseTarget srcTarget("srcTarget", buildcc::TargetType::Executable, diff --git a/buildcc/lib/target/test/target/test_target_user_deps.cpp b/buildcc/lib/target/test/target/test_target_user_deps.cpp index 50e51c64..686ca0d9 100644 --- a/buildcc/lib/target/test/target/test_target_user_deps.cpp +++ b/buildcc/lib/target/test/target/test_target_user_deps.cpp @@ -27,8 +27,9 @@ TEST_GROUP(TargetTestUserDepsGroup) }; // clang-format on -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); +static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", + "ar", "ld")); static const fs::path target_source_intermediate_path = fs::path(BUILD_TARGET_USER_DEPS_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp index 54344e46..d6308a89 100644 --- a/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp +++ b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp @@ -15,8 +15,9 @@ TEST_GROUP(ToolchainFlagApiTestGroup) // clang-format on TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Lock) { - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); toolchain.Lock(); CHECK_THROWS(std::exception, toolchain.AddPreprocessorFlag("-preprocessor")); CHECK_THROWS(std::exception, toolchain.AddAsmCompileFlag("-asm")); @@ -29,8 +30,9 @@ TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Lock) { } TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Unlock) { - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); toolchain.AddPreprocessorFlag("-preprocessor"); toolchain.AddAsmCompileFlag("-asm"); toolchain.AddPchCompileFlag("-pchcompile"); @@ -55,8 +57,9 @@ TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Unlock) { } TEST(ToolchainFlagApiTestGroup, BasicTargetTest) { - buildcc::Toolchain toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", - "g++", "ar", "ld"); + buildcc::Toolchain toolchain( + buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); toolchain.AddPreprocessorFlag("-preprocessor"); toolchain.AddAsmCompileFlag("-asm"); diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 41c92137..55eeb30e 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -45,17 +45,6 @@ class Toolchain : public internal::FlagApi, : id_(id), name_(name), executables_(executables), config_(config), lock_(false) {} - [[deprecated]] Toolchain(ToolchainId id, std::string_view name, - std::string_view assembler, - std::string_view c_compiler, - std::string_view cpp_compiler, - std::string_view archiver, std::string_view linker, - const ToolchainConfig &config = ToolchainConfig()) - : Toolchain(id, name, - ToolchainExecutables(assembler, c_compiler, cpp_compiler, - archiver, linker), - config) {} - virtual ~Toolchain() = default; Toolchain(Toolchain &&) = default; Toolchain &operator=(Toolchain &&) = default; diff --git a/buildcc/lib/toolchain/test/test_toolchain_find.cpp b/buildcc/lib/toolchain/test/test_toolchain_find.cpp index 3867b8ac..9b67961a 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_find.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_find.cpp @@ -26,8 +26,9 @@ TEST_GROUP(ToolchainFindTestGroup) // clang-format on TEST(ToolchainFindTestGroup, FindToolchain_ThroughEnvVar) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + buildcc::Toolchain gcc( + buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path().string()); @@ -46,8 +47,9 @@ TEST(ToolchainFindTestGroup, FindToolchain_ThroughEnvVar) { } TEST(ToolchainFindTestGroup, FindToolchain_ThroughAbsolutePath) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + buildcc::Toolchain gcc( + buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); buildcc::ToolchainFindConfig config; config.absolute_search_paths.insert(fs::current_path() / "toolchains" / @@ -59,8 +61,9 @@ TEST(ToolchainFindTestGroup, FindToolchain_ThroughAbsolutePath) { } TEST(ToolchainFindTestGroup, FindToolchain_DirectoryDoesntExist) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + buildcc::Toolchain gcc( + buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); buildcc::ToolchainFindConfig config; config.absolute_search_paths.insert(fs::current_path() / "toolchains" / @@ -72,8 +75,9 @@ TEST(ToolchainFindTestGroup, FindToolchain_DirectoryDoesntExist) { } TEST(ToolchainFindTestGroup, FindToolchain_NoDirectoryFound) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + buildcc::Toolchain gcc( + buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); buildcc::ToolchainFindConfig config; config.absolute_search_paths.insert(fs::current_path() / "toolchains" / @@ -85,8 +89,9 @@ TEST(ToolchainFindTestGroup, FindToolchain_NoDirectoryFound) { } TEST(ToolchainFindTestGroup, FindToolchain_NoToolchainFound) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + buildcc::Toolchain gcc( + buildcc::ToolchainId::Gcc, "gcc", + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); buildcc::ToolchainFindConfig config; config.absolute_search_paths.insert(fs::current_path() / "toolchains"); diff --git a/buildcc/plugins/include/plugins/buildcc_find.h b/buildcc/plugins/include/plugins/buildcc_find.h index 1c8f3661..50eab64e 100644 --- a/buildcc/plugins/include/plugins/buildcc_find.h +++ b/buildcc/plugins/include/plugins/buildcc_find.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "env/host_os.h" diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake index c7c1371a..b3c996f8 100644 --- a/buildcc/schema/cmake/schema.cmake +++ b/buildcc/schema/cmake/schema.cmake @@ -18,7 +18,7 @@ if (${TESTING}) ) target_link_libraries(mock_schema PUBLIC mock_env - flatbuffers_header_only + flatbuffers CppUTest CppUTestExt @@ -77,7 +77,7 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) target_compile_options(schema PRIVATE ${BUILD_COMPILE_FLAGS}) target_link_options(schema PRIVATE ${BUILD_LINK_FLAGS}) target_link_libraries(schema PRIVATE - flatbuffers_header_only + flatbuffers ) add_dependencies(schema fbs_to_header) endif() diff --git a/cmake/target/flatbuffers.cmake b/cmake/target/flatbuffers.cmake index 0c59684b..dc4e1c1b 100644 --- a/cmake/target/flatbuffers.cmake +++ b/cmake/target/flatbuffers.cmake @@ -6,29 +6,8 @@ set(FLATBUFFERS_BUILD_CPP17 ON CACHE BOOL "Flatbuffers C++17 support") set(FLATBUFFERS_BUILD_TESTS OFF CACHE BOOL "Flatbuffers build tests") set(FLATBUFFERS_BUILD_FLATC ${BUILDCC_FLATBUFFERS_FLATC} CACHE BOOL "Flatbuffers build flatc") set(FLATBUFFERS_BUILD_FLATHASH OFF CACHE BOOL "Flatbuffers build flathash") -set(FLATBUFFERS_BUILD_FLATLIB OFF CACHE BOOL "Flatbuffers build flatlib") +set(FLATBUFFERS_BUILD_FLATLIB ON CACHE BOOL "Flatbuffers build flatlib") set(FLATBUFFERS_LIBCXX_WITH_CLANG OFF CACHE BOOL "Flatbuffers LIBCXX") set(FLATBUFFERS_INSTALL ON CACHE BOOL "Enable the installation of targets.") set(FLATBUFFERS_ENABLE_PCH ${BUILDCC_PRECOMPILE_HEADERS} CACHE BOOL "Flatbuffers PCH") add_subdirectory(third_party/flatbuffers) - -set(FBS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/flatbuffers/include/flatbuffers") -set(FBS_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/flatbuffers/include") -file(GLOB FLATBUFFERS_INCLUDE_HEADERS "${FBS_DIR}/*.h") -if(${BUILDCC_PRECOMPILE_HEADERS}) - list(APPEND FLATBUFFERS_INCLUDE_HEADERS ${FBS_DIR}/pch/pch.h) -endif() - -add_library(flatbuffers_header_only INTERFACE - ${FLATBUFFERS_INCLUDE_HEADERS} -) -target_include_directories(flatbuffers_header_only INTERFACE - $ - $ -) - -if (${BUILDCC_INSTALL}) - install(TARGETS flatbuffers_header_only DESTINATION lib EXPORT flatbuffers_header_onlyConfig) - install(DIRECTORY ${FBS_INCLUDE_DIR} DESTINATION "include") - install(EXPORT flatbuffers_header_onlyConfig DESTINATION "lib/cmake/flatbuffers_header_only") -endif() diff --git a/doc/software_architecture/buildcc_interface_lib.PNG b/doc/software_architecture/buildcc_interface_lib.PNG index e0ce861cdf35a76ad446c2d7baef8f91af99cc0d..6fac4da17e92298a77b44612286e647611123e87 100644 GIT binary patch literal 151647 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
yArq6faj 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 XYuEHstXlMwf5Fsf>ZIfev)BC}lALgV literal 144370 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 VYMv!tT_fLRK6&P(#0d+2{C^Dw;lcm_ literal 132243 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�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

>bLU1nD5Kt*X9A;Wt$|=~eabp>- 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 e|ND#kxZGsUY6bBC diff --git a/docs/source/arch/cmake_boilerplate.rst b/docs/source/arch/cmake_boilerplate.rst index d4ac48cf..9a882cea 100644 --- a/docs/source/arch/cmake_boilerplate.rst +++ b/docs/source/arch/cmake_boilerplate.rst @@ -57,7 +57,7 @@ We can then ``add_subdirectory`` that particular folder. This helps us keep our ${CMAKE_CURRENT_SOURCE_DIR}/mock/include ) target_link_libraries(mock_env PUBLIC - fmt::fmt-header-only + fmt::fmt Taskflow CppUTest @@ -122,11 +122,11 @@ We can then ``add_subdirectory`` that particular folder. This helps us keep our $ $ ) - target_link_libraries(env PUBLIC fmt::fmt-header-only) + target_link_libraries(env PUBLIC fmt::fmt) target_compile_options(env PRIVATE ${BUILD_COMPILE_FLAGS}) target_link_options(env PRIVATE ${BUILD_LINK_FLAGS}) target_link_libraries(env PRIVATE - spdlog::spdlog_header_only + spdlog::spdlog tiny-process-library::tiny-process-library ) endif() diff --git a/docs/source/examples/gcc.rst b/docs/source/examples/gcc.rst index ee5e0246..c67e3289 100644 --- a/docs/source/examples/gcc.rst +++ b/docs/source/examples/gcc.rst @@ -218,7 +218,7 @@ Use BuildCC with CMake # fmt is imported by spdlog by default find_package(fmt_package NAMES "fmt" REQUIRED) find_package(spdlog_package NAMES "spdlog" REQUIRED) - find_package(flatbuffers_header_only_package NAMES "flatbuffers_header_only" REQUIRED) + find_package(flatbuffers_package NAMES "flatbuffers" REQUIRED) find_package(taskflow_package NAMES "Taskflow" "taskflow" REQUIRED) find_package(CLI11_package NAMES "CLI11" REQUIRED) find_package(tiny_process_library_package NAMES "tiny-process-library" REQUIRED) @@ -227,7 +227,7 @@ Use BuildCC with CMake message("Find package: ${fmt_package_DIR}") message("Find package: ${spdlog_package_DIR}") - message("Find package: ${flatbuffers_header_only_package_DIR}") + message("Find package: ${flatbuffers_package_DIR}") message("Find package: ${taskflow_package_DIR}") message("Find package: ${CLI11_package_DIR}") message("Find package: ${tiny_process_library_package_DIR}") # diff --git a/example/gcc/AfterInstall/CMakeLists.txt b/example/gcc/AfterInstall/CMakeLists.txt index 6848d43a..9445c04c 100644 --- a/example/gcc/AfterInstall/CMakeLists.txt +++ b/example/gcc/AfterInstall/CMakeLists.txt @@ -12,7 +12,7 @@ project(simple) # fmt is imported by spdlog by default find_package(fmt_package NAMES "fmt" REQUIRED) find_package(spdlog_package NAMES "spdlog" REQUIRED) -find_package(flatbuffers_header_only_package NAMES "flatbuffers_header_only" REQUIRED) +find_package(flatbuffers_package NAMES "Flatbuffers" "flatbuffers" REQUIRED) find_package(taskflow_package NAMES "Taskflow" "taskflow" REQUIRED) find_package(CLI11_package NAMES "CLI11" REQUIRED) find_package(tiny_process_library_package NAMES "tiny-process-library" REQUIRED) @@ -21,7 +21,7 @@ find_package(buildcc_package NAMES "buildcc" REQUIRED) message("Find package: ${fmt_package_DIR}") message("Find package: ${spdlog_package_DIR}") -message("Find package: ${flatbuffers_header_only_package_DIR}") +message("Find package: ${flatbuffers_package_DIR}") message("Find package: ${taskflow_package_DIR}") message("Find package: ${CLI11_package_DIR}") message("Find package: ${tiny_process_library_package_DIR}") # From 7ee1538e6d231319cbed0be31dcc1a0cfe10a9cd Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 11 May 2022 20:34:49 -0700 Subject: [PATCH 19/35] Custom generator (#212) --- bootstrap/src/build_buildcc.cpp | 6 +- buildcc/buildcc.h | 1 + buildcc/lib/env/src/command.cpp | 9 +- .../lib/target/cmake/common_target_src.cmake | 2 + buildcc/lib/target/cmake/mock_target.cmake | 3 + buildcc/lib/target/cmake/target.cmake | 2 + .../target/include/target/custom_generator.h | 174 ++++ buildcc/lib/target/include/target/generator.h | 6 +- .../target/interface/builder_interface.h | 60 ++ .../mock/custom_generator/recheck_states.cpp | 43 + .../target/mock/custom_generator/runner.cpp | 13 + .../lib/target/mock/expect_custom_generator.h | 23 + .../src/custom_generator/custom_generator.cpp | 239 ++++++ .../src/custom_generator/recheck_states.cpp | 25 + buildcc/lib/target/test/target/CMakeLists.txt | 8 + .../test/target/test_builder_interface.cpp | 64 ++ .../test/target/test_custom_generator.cpp | 742 ++++++++++++++++++ buildcc/plugins/CMakeLists.txt | 19 +- buildcc/schema/cmake/schema.cmake | 12 +- buildcc/schema/cmake/schema_generate.cmake | 2 + buildcc/schema/custom_generator.fbs | 32 + .../schema/custom_generator_serialization.h | 61 ++ .../src/custom_generator_serialization.cpp | 84 ++ buildcc/schema/test/.gitignore | 1 + buildcc/schema/test/dump/.gitkeep | 0 .../test_custom_generator_serialization.cpp | 83 ++ buildcc/toolchains/CMakeLists.txt | 2 +- 27 files changed, 1699 insertions(+), 17 deletions(-) create mode 100644 buildcc/lib/target/include/target/custom_generator.h create mode 100644 buildcc/lib/target/mock/custom_generator/recheck_states.cpp create mode 100644 buildcc/lib/target/mock/custom_generator/runner.cpp create mode 100644 buildcc/lib/target/mock/expect_custom_generator.h create mode 100644 buildcc/lib/target/src/custom_generator/custom_generator.cpp create mode 100644 buildcc/lib/target/src/custom_generator/recheck_states.cpp create mode 100644 buildcc/lib/target/test/target/test_custom_generator.cpp create mode 100644 buildcc/schema/custom_generator.fbs create mode 100644 buildcc/schema/include/schema/custom_generator_serialization.h create mode 100644 buildcc/schema/src/custom_generator_serialization.cpp create mode 100644 buildcc/schema/test/.gitignore create mode 100644 buildcc/schema/test/dump/.gitkeep create mode 100644 buildcc/schema/test/test_custom_generator_serialization.cpp diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index e655a418..cae0ad44 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -20,10 +20,13 @@ namespace buildcc { void schema_gen_cb(BaseGenerator &generator, const BaseTarget &flatc_exe) { generator.AddInput("{gen_root_dir}/path.fbs", "path_fbs"); + generator.AddInput("{gen_root_dir}/custom_generator.fbs", + "custom_generator_fbs"); generator.AddInput("{gen_root_dir}/generator.fbs", "generator_fbs"); generator.AddInput("{gen_root_dir}/target.fbs", "target_fbs"); generator.AddOutput("{gen_build_dir}/path_generated.h"); + generator.AddOutput("{gen_build_dir}/custom_generator_generated.h"); generator.AddOutput("{gen_build_dir}/generator_generated.h"); generator.AddOutput("{gen_build_dir}/target_generated.h"); @@ -33,7 +36,7 @@ void schema_gen_cb(BaseGenerator &generator, const BaseTarget &flatc_exe) { // generator.AddCommand("{flatc_compiler} --help"); generator.AddCommand( "{flatc_compiler} -o {gen_build_dir} -I {gen_root_dir} --gen-object-api " - "--cpp {path_fbs} {generator_fbs} {target_fbs}"); + "--cpp {path_fbs} {custom_generator_fbs} {generator_fbs} {target_fbs}"); generator.Build(); } @@ -71,6 +74,7 @@ void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, // TARGET target.GlobSources("lib/target/src/common"); + target.GlobSources("lib/target/src/custom_generator"); target.GlobSources("lib/target/src/generator"); target.GlobSources("lib/target/src/api"); target.GlobSources("lib/target/src/target_info"); diff --git a/buildcc/buildcc.h b/buildcc/buildcc.h index 8f08c5db..e73bbffe 100644 --- a/buildcc/buildcc.h +++ b/buildcc/buildcc.h @@ -31,6 +31,7 @@ // Base #include "toolchain/toolchain.h" +#include "target/custom_generator.h" #include "target/generator.h" #include "target/target_info.h" #include "target/target.h" diff --git a/buildcc/lib/env/src/command.cpp b/buildcc/lib/env/src/command.cpp index 6620c37e..2962aa24 100644 --- a/buildcc/lib/env/src/command.cpp +++ b/buildcc/lib/env/src/command.cpp @@ -61,7 +61,14 @@ std::string Command::Construct( }); // Construct your command - return fmt::vformat(pattern, store); + std::string ret; + try { + ret = fmt::vformat(pattern, store); + } catch (const std::exception &e) { + env::assert_fatal( + fmt::format("Construct command failed: {}", e.what())); + } + return ret; } } // namespace buildcc::env diff --git a/buildcc/lib/target/cmake/common_target_src.cmake b/buildcc/lib/target/cmake/common_target_src.cmake index 76564d86..31ab0a03 100644 --- a/buildcc/lib/target/cmake/common_target_src.cmake +++ b/buildcc/lib/target/cmake/common_target_src.cmake @@ -34,6 +34,8 @@ set(COMMON_TARGET_SRCS include/target/api/target_getter.h # Generator + src/custom_generator/custom_generator.cpp + include/target/custom_generator.h src/generator/generator.cpp include/target/generator.h diff --git a/buildcc/lib/target/cmake/mock_target.cmake b/buildcc/lib/target/cmake/mock_target.cmake index 2d648938..cf2b6bde 100644 --- a/buildcc/lib/target/cmake/mock_target.cmake +++ b/buildcc/lib/target/cmake/mock_target.cmake @@ -1,5 +1,8 @@ add_library(mock_target STATIC ${COMMON_TARGET_SRCS} + # Custom Generator mocks + mock/custom_generator/runner.cpp + mock/custom_generator/recheck_states.cpp # Generator mocks src/generator/task.cpp diff --git a/buildcc/lib/target/cmake/target.cmake b/buildcc/lib/target/cmake/target.cmake index 98f16479..931b1c46 100644 --- a/buildcc/lib/target/cmake/target.cmake +++ b/buildcc/lib/target/cmake/target.cmake @@ -1,6 +1,8 @@ set(TARGET_SRCS ${COMMON_TARGET_SRCS} + src/custom_generator/recheck_states.cpp + src/generator/task.cpp src/generator/recheck_states.cpp diff --git a/buildcc/lib/target/include/target/custom_generator.h b/buildcc/lib/target/include/target/custom_generator.h new file mode 100644 index 00000000..8c10ee28 --- /dev/null +++ b/buildcc/lib/target/include/target/custom_generator.h @@ -0,0 +1,174 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TARGET_CUSTOM_GENERATOR_H_ +#define TARGET_CUSTOM_GENERATOR_H_ + +#include +#include +#include +#include + +#include "taskflow/taskflow.hpp" + +#include "env/command.h" +#include "env/task_state.h" + +#include "target/interface/builder_interface.h" + +#include "schema/custom_generator_serialization.h" +#include "schema/path.h" + +#include "target/common/target_env.h" + +namespace buildcc { + +// TODO, Shift to a different file +// TODO, Check if we need the "id" here as well +class CustomGeneratorContext { +public: + CustomGeneratorContext(const env::Command &c, const fs_unordered_set &i, + const fs_unordered_set &o) + : command(c), inputs(i), outputs(o) {} + +public: + const env::Command &command; + const fs_unordered_set &inputs; + const fs_unordered_set &outputs; +}; + +// clang-format off +typedef std::function GenerateCb; + +typedef std::function &)> DependencyCb; +// clang-format on + +struct UserRelInputOutputSchema : internal::RelInputOutputSchema { + fs_unordered_set inputs; + GenerateCb generate_cb; +}; + +struct UserCustomGeneratorSchema : public internal::CustomGeneratorSchema { + std::unordered_map rels_map; + + void ConvertToInternal() { + for (auto &r_miter : rels_map) { + r_miter.second.internal_inputs = path_schema_convert( + r_miter.second.inputs, internal::Path::CreateExistingPath); + auto p = internal_rels_map.emplace(r_miter.first, r_miter.second); + env::assert_fatal(p.second, + fmt::format("Could not save {}", r_miter.first)); + } + } +}; + +class CustomGenerator : public internal::BuilderInterface { +public: + CustomGenerator(const std::string &name, const TargetEnv &env) + : name_(name), + env_(env.GetTargetRootDir(), env.GetTargetBuildDir() / name), + serialization_(env_.GetTargetBuildDir() / fmt::format("{}.bin", name)) { + Initialize(); + } + virtual ~CustomGenerator() = default; + CustomGenerator(const CustomGenerator &) = delete; + + /** + * @brief Add default arguments for input, output and command requirements + * + * @param arguments Key-Value pair for arguments + */ + void AddDefaultArguments( + const std::unordered_map &arguments); + + /** + * @brief Single Generator task for inputs->generate_cb->outputs + * + * @param id Unique id associated with Generator task + * @param inputs File inputs + * @param outputs File outputs + * @param generate_cb User-defined generate callback to build outputs from the + * provided inputs + */ + void AddGenInfo(const std::string &id, const fs_unordered_set &inputs, + const fs_unordered_set &outputs, + const GenerateCb &generate_cb); + + // Callbacks + /** + * @brief Setup dependencies between Tasks using their `id` + * For example: `task_map["id1"].precede(task_map["id2"])` + * + * IMPORTANT: Successor tasks will not automatically run if dependent task is + * run. + * The Dependency callback only sets precedence (order in which your tasks + * should run) + * Default behaviour when dependency callback is not supplied: All task `id`s + * run in parallel. + * + * @param dependency_cb Unordered map of `id` and `task` + * The map can be safely mutated. + */ + void AddDependencyCb(const DependencyCb &dependency_cb); + + void Build() override; + + // Getters + const fs::path &GetBinaryPath() const { + return serialization_.GetSerializedFile(); + } + const fs::path &GetRootDir() const { return env_.GetTargetRootDir(); } + const fs::path &GetBuildDir() const { return env_.GetTargetBuildDir(); } + tf::Taskflow &GetTaskflow() { return tf_; } + +private: + void Initialize(); + + template void TaskRunner(const std::string &id); + + void GenerateTask(); + void BuildGenerate(std::unordered_map + &gen_selected_map, + std::unordered_map + &dummy_gen_selected_map); + + // Recheck states + void IdRemoved(); + void IdAdded(); + void IdUpdated(); + +private: + std::string name_; + TargetEnv env_; + internal::CustomGeneratorSerialization serialization_; + + // Serialization + UserCustomGeneratorSchema user_; + + std::mutex success_schema_mutex_; + std::unordered_map success_schema_; + + // Internal + env::Command command_; + tf::Taskflow tf_; + + // Callbacks + DependencyCb dependency_cb_; +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/lib/target/include/target/generator.h b/buildcc/lib/target/include/target/generator.h index 74f9612a..3784e991 100644 --- a/buildcc/lib/target/include/target/generator.h +++ b/buildcc/lib/target/include/target/generator.h @@ -17,7 +17,6 @@ #ifndef TARGET_GENERATOR_H_ #define TARGET_GENERATOR_H_ -#include #include #include #include @@ -25,7 +24,6 @@ #include "taskflow/taskflow.hpp" -#include "env/env.h" #include "env/task_state.h" #include "env/command.h" @@ -54,8 +52,8 @@ class Generator : public internal::BuilderInterface { parallel_(parallel) { Initialize(); } - virtual ~Generator() {} - Generator(const Generator &generator) = delete; + virtual ~Generator() = default; + Generator(const Generator &) = delete; /** * @brief Add default arguments for input, output and command requirements diff --git a/buildcc/lib/target/include/target/interface/builder_interface.h b/buildcc/lib/target/include/target/interface/builder_interface.h index ae044274..22fbb7ba 100644 --- a/buildcc/lib/target/include/target/interface/builder_interface.h +++ b/buildcc/lib/target/include/target/interface/builder_interface.h @@ -27,6 +27,66 @@ namespace buildcc::internal { +enum PathState { + kNoChange, + kRemoved, + kAdded, + kUpdated, +}; + +template +inline bool CheckChanged(const T &previous, const T ¤t) { + bool changed = false; + if (previous != current) { + changed = true; + } + return changed; +} + +/** + * @brief + * + * @return PathState Returns first state found if `Removed`, `Added` or + * `Updated` + * If none of the above states are true then it returns `NoChange` + */ +inline PathState CheckPaths(const internal::path_unordered_set &previous_path, + const internal::path_unordered_set ¤t_path) { + PathState state{PathState::kNoChange}; + + // * Old path is removed + const bool removed = std::any_of( + previous_path.begin(), previous_path.end(), [&](const internal::Path &p) { + return current_path.find(p) == current_path.end(); + }); + if (removed) { + state = PathState::kRemoved; + } else { + (void)std::any_of(current_path.cbegin(), current_path.cend(), + [&](const internal::Path &p) -> bool { + bool dirty = false; + const auto find = previous_path.find(p); + const bool added_cond = (find == previous_path.end()); + if (added_cond) { + dirty = true; + state = kAdded; + } else { + const bool updated_cond = + (p.GetLastWriteTimestamp() > + find->GetLastWriteTimestamp()); + if (updated_cond) { + dirty = true; + state = kUpdated; + } else { + dirty = false; + } + } + return dirty; + }); + } + return state; +} + // TODO, 1. Consider updating Recheck* APIs - do not modify internal `dirty_` // flag // TODO, 2. Consider removing dependency on target/common/util.h diff --git a/buildcc/lib/target/mock/custom_generator/recheck_states.cpp b/buildcc/lib/target/mock/custom_generator/recheck_states.cpp new file mode 100644 index 00000000..c8c6471c --- /dev/null +++ b/buildcc/lib/target/mock/custom_generator/recheck_states.cpp @@ -0,0 +1,43 @@ +#include "target/custom_generator.h" + +#include "expect_custom_generator.h" + +#include "CppUTestExt/MockSupport.h" + +namespace buildcc { + +static constexpr const char *const ID_REMOVED_FUNCTION = + "CustomGenerator::IdRemoved"; +static constexpr const char *const ID_ADDED_FUNCTION = + "CustomGenerator::IdAdded"; +static constexpr const char *const ID_UPDATED_FUNCTION = + "CustomGenerator::IdUpdated"; + +void CustomGenerator::IdRemoved() { + mock().actualCall(ID_REMOVED_FUNCTION).onObject(this); +} +void CustomGenerator::IdAdded() { + mock().actualCall(ID_ADDED_FUNCTION).onObject(this); +} +void CustomGenerator::IdUpdated() { + mock().actualCall(ID_UPDATED_FUNCTION).onObject(this); +} + +namespace m { + +void CustomGeneratorExpect_IdRemoved(unsigned int calls, + CustomGenerator *generator) { + mock().expectNCalls(calls, ID_REMOVED_FUNCTION).onObject(generator); +} +void CustomGeneratorExpect_IdAdded(unsigned int calls, + CustomGenerator *generator) { + mock().expectNCalls(calls, ID_ADDED_FUNCTION).onObject(generator); +} +void CustomGeneratorExpect_IdUpdated(unsigned int calls, + CustomGenerator *generator) { + mock().expectNCalls(calls, ID_UPDATED_FUNCTION).onObject(generator); +} + +} // namespace m + +} // namespace buildcc diff --git a/buildcc/lib/target/mock/custom_generator/runner.cpp b/buildcc/lib/target/mock/custom_generator/runner.cpp new file mode 100644 index 00000000..8014c851 --- /dev/null +++ b/buildcc/lib/target/mock/custom_generator/runner.cpp @@ -0,0 +1,13 @@ +#include "target/custom_generator.h" + +#include "expect_custom_generator.h" + +namespace buildcc::m { + +void CustomGeneratorRunner(CustomGenerator &custom_generator) { + tf::Executor executor(1); + executor.run(custom_generator.GetTaskflow()); + executor.wait_for_all(); +} + +} // namespace buildcc::m diff --git a/buildcc/lib/target/mock/expect_custom_generator.h b/buildcc/lib/target/mock/expect_custom_generator.h new file mode 100644 index 00000000..f54ed17c --- /dev/null +++ b/buildcc/lib/target/mock/expect_custom_generator.h @@ -0,0 +1,23 @@ +#ifndef TARGET_MOCK_EXPECT_CUSTOM_GENERATOR_H_ +#define TARGET_MOCK_EXPECT_CUSTOM_GENERATOR_H_ + +#include "target/custom_generator.h" + +namespace buildcc::m { + +/** + * @brief Runs the generator using Taskflow with 1 thread + * CppUTest cannot mock with multiple threads + */ +void CustomGeneratorRunner(CustomGenerator &custom_generator); + +void CustomGeneratorExpect_IdRemoved(unsigned int calls, + CustomGenerator *generator); +void CustomGeneratorExpect_IdAdded(unsigned int calls, + CustomGenerator *generator); +void CustomGeneratorExpect_IdUpdated(unsigned int calls, + CustomGenerator *generator); + +} // namespace buildcc::m + +#endif diff --git a/buildcc/lib/target/src/custom_generator/custom_generator.cpp b/buildcc/lib/target/src/custom_generator/custom_generator.cpp new file mode 100644 index 00000000..8d980c3f --- /dev/null +++ b/buildcc/lib/target/src/custom_generator/custom_generator.cpp @@ -0,0 +1,239 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "target/custom_generator.h" + +namespace { +constexpr const char *const kStartGeneratorTaskName = "Start Generator"; +constexpr const char *const kEndGeneratorTaskName = "End Generator"; + +constexpr const char *const kCommandTaskName = "Command"; +constexpr const char *const kGenerateTaskName = "Generate"; + +} // namespace + +namespace buildcc { + +void CustomGenerator::AddDefaultArguments( + const std::unordered_map &arguments) { + for (const auto &arg_iter : arguments) { + command_.AddDefaultArgument(arg_iter.first, + command_.Construct(arg_iter.second)); + } +} + +void CustomGenerator::AddGenInfo(const std::string &id, + const fs_unordered_set &inputs, + const fs_unordered_set &outputs, + const GenerateCb &generate_cb) { + env::assert_fatal(user_.rels_map.find(id) == user_.rels_map.end(), + fmt::format("Duplicate id {} detected", id)); + ASSERT_FATAL(generate_cb, "Invalid callback provided"); + + UserRelInputOutputSchema schema; + for (const auto &i : inputs) { + schema.inputs.emplace(command_.Construct(path_as_string(i))); + } + for (const auto &o : outputs) { + schema.outputs.emplace(command_.Construct(path_as_string(o))); + } + schema.generate_cb = generate_cb; + user_.rels_map.emplace(id, std::move(schema)); +} + +void CustomGenerator::AddDependencyCb(const DependencyCb &dependency_cb) { + dependency_cb_ = dependency_cb; +} + +void CustomGenerator::Build() { + (void)serialization_.LoadFromFile(); + + GenerateTask(); +} + +// PRIVATE +void CustomGenerator::Initialize() { + // Checks + env::assert_fatal( + Project::IsInit(), + "Environment is not initialized. Use the buildcc::Project::Init API"); + + // + fs::create_directories(env_.GetTargetBuildDir()); + command_.AddDefaultArguments({ + {"gen_root_dir", path_as_string(env_.GetTargetRootDir())}, + {"gen_build_dir", path_as_string(env_.GetTargetBuildDir())}, + }); + + // + unique_id_ = name_; + tf_.name(name_); +} + +void CustomGenerator::BuildGenerate( + std::unordered_map &gen_selected_map, + std::unordered_map + &dummy_gen_selected_map) { + if (!serialization_.IsLoaded()) { + gen_selected_map = user_.rels_map; + dirty_ = true; + } else { + // DONE, Conditionally select internal_rels depending on what has changed + const auto &prev_rels = serialization_.GetLoad().internal_rels_map; + const auto &curr_rels = user_.rels_map; + + // DONE, MAP REMOVED condition Check if prev_rels exists in curr_rels + // If prev_rels does not exist in curr_rels, has been removed from existing + // build + // We need this condition to only set the dirty_ flag + for (const auto &prev_miter : prev_rels) { + const auto &id = prev_miter.first; + if (curr_rels.find(id) == curr_rels.end()) { + // MAP REMOVED condition + IdRemoved(); + dirty_ = true; + break; + } + } + + // DONE, MAP ADDED condition Check if curr_rels exists in prev_rels + // If curr_rels does not exist in prev_rels, has been added to existing + // build + for (const auto &curr_miter : curr_rels) { + const auto &id = curr_miter.first; + if (prev_rels.find(id) == prev_rels.end()) { + // MAP ADDED condition + IdAdded(); + gen_selected_map.emplace(curr_miter.first, curr_miter.second); + dirty_ = true; + } else { + // MAP UPDATED condition (*checked later) + // This is because tasks can have dependencies amongst each other we can + // compute task level rebuilds later + dummy_gen_selected_map.emplace(curr_miter.first, curr_miter.second); + } + } + } +} + +void CustomGenerator::GenerateTask() { + tf::Task generate_task = tf_.emplace([&](tf::Subflow &subflow) { + if (env::get_task_state() != env::TaskState::SUCCESS) { + return; + } + + try { + std::unordered_map + selected_user_schema; + std::unordered_map + dummy_selected_user_schema; + BuildGenerate(selected_user_schema, dummy_selected_user_schema); + + std::unordered_map task_map; + // Create task for selected schema + for (const auto &selected_miter : selected_user_schema) { + const auto &id = selected_miter.first; + tf::Task task = subflow + .emplace([&]() { + try { + TaskRunner(id); + } catch (...) { + env::set_task_state(env::TaskState::FAILURE); + } + }) + .name(id); + task_map.emplace(id, task); + } + + for (auto &dummy_selected_miter : dummy_selected_user_schema) { + const auto &id = dummy_selected_miter.first; + auto ¤t_info = dummy_selected_miter.second; + tf::Task task = subflow + .emplace([&]() { + try { + user_.rels_map.at(id).internal_inputs = + internal::path_schema_convert( + current_info.inputs, + internal::Path::CreateExistingPath); + TaskRunner(id); + } catch (...) { + env::set_task_state(env::TaskState::FAILURE); + } + }) + .name(id); + task_map.emplace(id, task); + } + + // Dependencies between ids + if (dependency_cb_) { + try { + dependency_cb_(task_map); + } catch (...) { + env::log_critical(__FUNCTION__, "Dependency callback failed"); + env::set_task_state(env::TaskState::FAILURE); + } + } + + // NOTE, Do not call detach otherwise this will fail + subflow.join(); + + // Store dummy_selected and successfully run schema + if (dirty_) { + UserCustomGeneratorSchema user_final_schema; + user_final_schema.rels_map.insert(success_schema_.begin(), + success_schema_.end()); + + user_final_schema.ConvertToInternal(); + serialization_.UpdateStore(user_final_schema); + env::assert_fatal(serialization_.StoreToFile(), + fmt::format("Store failed for {}", name_)); + } + + } catch (...) { + env::set_task_state(env::TaskState::FAILURE); + } + }); + // TODO, Instead of "Generate" name the task of user's choice + generate_task.name(kGenerateTaskName); +} + +template void CustomGenerator::TaskRunner(const std::string &id) { + const auto ¤t_info = user_.rels_map.at(id); + bool rerun = false; + if constexpr (run) { + rerun = true; + } else { + const auto &previous_info = + serialization_.GetLoad().internal_rels_map.at(id); + rerun = internal::CheckPaths(previous_info.internal_inputs, + current_info.internal_inputs) != + internal::PathState::kNoChange || + internal::CheckChanged(previous_info.outputs, current_info.outputs); + } + + if (rerun) { + dirty_ = true; + buildcc::CustomGeneratorContext ctx(command_, current_info.inputs, + current_info.outputs); + bool success = current_info.generate_cb(ctx); + env::assert_fatal(success, fmt::format("Generate Cb failed for id {}", id)); + } + + std::lock_guard guard(success_schema_mutex_); + success_schema_.emplace(id, current_info); +} + +} // namespace buildcc diff --git a/buildcc/lib/target/src/custom_generator/recheck_states.cpp b/buildcc/lib/target/src/custom_generator/recheck_states.cpp new file mode 100644 index 00000000..0ccc632c --- /dev/null +++ b/buildcc/lib/target/src/custom_generator/recheck_states.cpp @@ -0,0 +1,25 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "target/custom_generator.h" + +namespace buildcc { + +void CustomGenerator::IdRemoved() {} +void CustomGenerator::IdAdded() {} +void CustomGenerator::IdUpdated() {} + +} // namespace buildcc diff --git a/buildcc/lib/target/test/target/CMakeLists.txt b/buildcc/lib/target/test/target/CMakeLists.txt index 44acb230..a77da279 100644 --- a/buildcc/lib/target/test/target/CMakeLists.txt +++ b/buildcc/lib/target/test/target/CMakeLists.txt @@ -42,11 +42,19 @@ target_link_libraries(test_target_state PRIVATE target_interface) add_test(NAME test_target_state COMMAND test_target_state) # Generator +add_executable(test_custom_generator + test_custom_generator.cpp +) +target_link_libraries(test_custom_generator PRIVATE target_interface) + add_executable(test_generator test_generator.cpp ) target_link_libraries(test_generator PRIVATE target_interface) +add_test(NAME test_custom_generator COMMAND test_custom_generator + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) add_test(NAME test_generator COMMAND test_generator WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/buildcc/lib/target/test/target/test_builder_interface.cpp b/buildcc/lib/target/test/target/test_builder_interface.cpp index 9cc2d2ac..ba1d02e9 100644 --- a/buildcc/lib/target/test/target/test_builder_interface.cpp +++ b/buildcc/lib/target/test/target/test_builder_interface.cpp @@ -62,6 +62,70 @@ TEST(TestBuilderInterfaceGroup, IncorrectUpdateRecheckCb) { CHECK_THROWS(std::exception, tbi.RecheckPathIncorrectUpdateCb()); } +TEST(TestBuilderInterfaceGroup, CheckChanged) { + std::vector previous{"", "v1"}; + std::vector current{"", "v1"}; + CHECK_FALSE(buildcc::internal::CheckChanged(previous, current)); + + current.clear(); + current.push_back(""); + CHECK_TRUE(buildcc::internal::CheckChanged(previous, current)); +} + +TEST(TestBuilderInterfaceGroup, CheckPaths) { + { + auto pathstate = buildcc::internal::CheckPaths( + { + buildcc::internal::Path::CreateNewPath("", 0x1234), + buildcc::internal::Path::CreateNewPath("v1", 0x2345), + }, + { + buildcc::internal::Path::CreateNewPath("", 0x1234), + buildcc::internal::Path::CreateNewPath("v1", 0x2345), + }); + CHECK_TRUE(pathstate == buildcc::internal::PathState::kNoChange); + } + + { + auto pathstate = buildcc::internal::CheckPaths( + { + buildcc::internal::Path::CreateNewPath("", 0x1234), + buildcc::internal::Path::CreateNewPath("v1", 0x2345), + }, + { + buildcc::internal::Path::CreateNewPath("", 0x1234), + }); + CHECK_TRUE(pathstate == buildcc::internal::PathState::kRemoved); + } + + { + auto pathstate = buildcc::internal::CheckPaths( + { + buildcc::internal::Path::CreateNewPath("", 0x1234), + buildcc::internal::Path::CreateNewPath("v1", 0x2345), + }, + { + buildcc::internal::Path::CreateNewPath("", 0x1234), + buildcc::internal::Path::CreateNewPath("v1", 0x2345), + buildcc::internal::Path::CreateNewPath("v2", 0x3456), + }); + CHECK_TRUE(pathstate == buildcc::internal::PathState::kAdded); + } + + { + auto pathstate = buildcc::internal::CheckPaths( + { + buildcc::internal::Path::CreateNewPath("", 0x1234), + buildcc::internal::Path::CreateNewPath("v1", 0x2345), + }, + { + buildcc::internal::Path::CreateNewPath("", 0x1234), + buildcc::internal::Path::CreateNewPath("v1", 0x3456), + }); + CHECK_TRUE(pathstate == buildcc::internal::PathState::kUpdated); + } +} + int main(int ac, char **av) { return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp new file mode 100644 index 00000000..27def93c --- /dev/null +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -0,0 +1,742 @@ +#include "target/custom_generator.h" + +#include "expect_command.h" +#include "expect_custom_generator.h" +#include "test_target_util.h" + +// #include "test_target_util.h" +// #include "taskflow/taskflow.hpp" +// #include "env/util.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(CustomGeneratorTestGroup) +{ + void teardown() { + mock().checkExpectations(); + mock().clear(); + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); + } +}; +// clang-format on + +fs::path BUILD_DIR = fs::current_path() / "intermediate" / "custom_generator"; + +static bool BasicGenerateCb(const buildcc::CustomGeneratorContext &ctx) { + (void)ctx; + return mock().actualCall("BasicGenerateCb").returnBoolValue(); +} + +TEST(CustomGeneratorTestGroup, Basic) { + buildcc::CustomGenerator cgen("basic", ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.Build(); + + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + buildcc::m::CustomGeneratorRunner(cgen); + + // Serialization check + { + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + + const auto &internal_map = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(internal_map.size(), 2); + const auto &id1_info = internal_map.at("id1"); + CHECK_EQUAL(id1_info.internal_inputs.size(), 1); + CHECK_EQUAL(id1_info.outputs.size(), 1); + + const auto &id2_info = internal_map.at("id2"); + CHECK_EQUAL(id2_info.internal_inputs.size(), 1); + CHECK_EQUAL(id2_info.outputs.size(), 0); + } +} + +TEST(CustomGeneratorTestGroup, Basic_Failure) { + buildcc::CustomGenerator cgen("basic_failure", ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, {}, BasicGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.Build(); + + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + mock().expectOneCall("BasicGenerateCb").andReturnValue(false); + buildcc::m::CustomGeneratorRunner(cgen); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); + + // Load + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + + const auto &internal_map = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(internal_map.size(), 1); +} + +TEST(CustomGeneratorTestGroup, DefaultArgumentUsage) { + buildcc::CustomGenerator cgen("default_argument_usage", ""); + cgen.AddDefaultArguments({ + {"dummy_main_c", "{gen_root_dir}/dummy_main.c"}, + {"dummy_main_o", "{gen_build_dir}/dummy_main.o"}, + {"dummy_main_cpp", "{gen_root_dir}/dummy_main.cpp"}, + }); + cgen.AddGenInfo("id1", {"{dummy_main_c}"}, {"{dummy_main_o}"}, + BasicGenerateCb); + cgen.AddGenInfo("id2", {"{dummy_main_cpp}"}, {}, BasicGenerateCb); + cgen.Build(); + + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + buildcc::m::CustomGeneratorRunner(cgen); + + // Serialization check + { + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + + const auto &internal_map = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(internal_map.size(), 2); + const auto &id1_info = internal_map.at("id1"); + CHECK_EQUAL(id1_info.internal_inputs.size(), 1); + CHECK_EQUAL(id1_info.outputs.size(), 1); + + const auto &id2_info = internal_map.at("id2"); + CHECK_EQUAL(id2_info.internal_inputs.size(), 1); + CHECK_EQUAL(id2_info.outputs.size(), 0); + } +} + +TEST(CustomGeneratorTestGroup, FailureCases) { + { + buildcc::CustomGenerator cgen("failure_no_cb", ""); + buildcc::GenerateCb cb; + CHECK_THROWS(std::exception, cgen.AddGenInfo("id1", {}, {}, cb)); + } + + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); + + { + buildcc::CustomGenerator cgen("failure_cannot_save", ""); + fs::create_directory( + cgen.GetBinaryPath()); // make a folder so that file cannot be saved + + cgen.AddGenInfo("id1", {}, {}, BasicGenerateCb); + cgen.AddGenInfo("id2", {}, {}, BasicGenerateCb); + cgen.Build(); + + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + buildcc::m::CustomGeneratorRunner(cgen); + + CHECK_TRUE(buildcc::env::get_task_state() == + buildcc::env::TaskState::FAILURE); + } + + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); + + { + buildcc::CustomGenerator cgen("gen_task_not_run_no_io", ""); + cgen.Build(); + + buildcc::m::CustomGeneratorRunner(cgen); + } + + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); + + { + buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE); + + buildcc::CustomGenerator cgen("gen_task_state_failure", ""); + cgen.AddGenInfo("id1", {}, {}, BasicGenerateCb); + cgen.Build(); + buildcc::m::CustomGeneratorRunner(cgen); + + CHECK_TRUE(buildcc::env::get_task_state() == + buildcc::env::TaskState::FAILURE); + } + + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); +} + +static bool Dep1Cb(const buildcc::CustomGeneratorContext &ctx) { + (void)ctx; + mock().actualCall("Dep1Cb"); + return buildcc::env::Command::Execute(""); +} + +static bool Dep2Cb(const buildcc::CustomGeneratorContext &ctx) { + (void)ctx; + mock().actualCall("Dep2Cb"); + return buildcc::env::Command::Execute(""); +} + +static void DependencyCb(std::unordered_map &task_map) { + task_map.at("id1").precede(task_map.at("id2")); +} + +TEST(CustomGeneratorTestGroup, AddDependency_BasicCheck) { + constexpr const char *const kGenName = "add_dependency_basic_check"; + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, Dep2Cb); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/dummy_main.o"}, Dep1Cb); + cgen.AddDependencyCb(DependencyCb); + cgen.Build(); + + mock().expectOneCall("Dep1Cb"); + buildcc::env::m::CommandExpect_Execute(1, true); + mock().expectOneCall("Dep2Cb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + } +} + +static bool FileDep1Cb(const buildcc::CustomGeneratorContext &ctx) { + mock().actualCall("FileDep1Cb"); + for (const auto &o : ctx.outputs) { + CHECK_TRUE(buildcc::env::save_file(o.string().c_str(), "", false)); + } + return true; +} + +static bool FileDep2Cb(const buildcc::CustomGeneratorContext &ctx) { + mock().actualCall("FileDep2Cb"); + for (const auto &i : ctx.inputs) { + CHECK_TRUE(fs::exists(i)); + } + return true; +} + +TEST(CustomGeneratorTestGroup, AddDependency_FileDep) { + constexpr const char *const kGenName = "add_dependency_file_dep"; + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddDependencyCb(DependencyCb); + cgen.Build(); + + mock().expectOneCall("FileDep1Cb"); + mock().expectOneCall("FileDep2Cb"); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + } +} + +TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { + constexpr const char *const kGenName = "add_dependency_file_dep_with_rebuild"; + + fs::path kInputFile = + (BUILD_DIR / kGenName / "dummy_main.c").make_preferred(); + UT_PRINT(kInputFile.string().c_str()); + fs::create_directories(BUILD_DIR / kGenName); + CHECK_TRUE(buildcc::env::save_file(kInputFile.string().c_str(), "", false)); + + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddDependencyCb(DependencyCb); + cgen.Build(); + + mock().expectOneCall("FileDep1Cb"); + mock().expectOneCall("FileDep2Cb"); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); + } + + // Same, no change + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddDependencyCb(DependencyCb); + cgen.Build(); + + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); + } + + // reset + fs::remove_all(BUILD_DIR / kGenName / "dummy_main.o"); + + // Remove id1, should cause id2 to fail + // NOTE, dirty_ == false is not made true when id2 is run, however id removed + // sets dirty_ == true + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddDependencyCb(DependencyCb); + cgen.Build(); + + buildcc::m::CustomGeneratorExpect_IdRemoved(1, &cgen); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 0); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); + } + + // reset + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); + fs::remove_all(BUILD_DIR / kGenName / "dummy_main.o"); + + // Added + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddDependencyCb(DependencyCb); + cgen.Build(); + + buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); + buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); + mock().expectOneCall("FileDep1Cb"); + mock().expectOneCall("FileDep2Cb"); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); + } + + // reset + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); + fs::remove_all(BUILD_DIR / kGenName / "dummy_main.o"); + + buildcc::m::blocking_sleep(1); + buildcc::env::save_file(kInputFile.string().c_str(), "", false); + + // Update id1:dummy_main.c -> updated dummy_main.o -> should rerun id2 as well + { + buildcc::CustomGenerator cgen(kGenName, ""); + + cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddDependencyCb(DependencyCb); + cgen.Build(); + + mock().expectOneCall("FileDep1Cb"); + mock().expectOneCall("FileDep2Cb"); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); + } + + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); +} + +static bool RealGenerateCb(const buildcc::CustomGeneratorContext &ctx) { + (void)ctx; + mock().actualCall("RealGenerateCb"); + return buildcc::env::Command::Execute(""); +} + +TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { + constexpr const char *const kGenName = "real_generator_basic"; + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.Build(); + + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + + fs::remove_all(cgen.GetBinaryPath()); + } + + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, {}, + RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, {}, RealGenerateCb); + cgen.Build(); + + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, false); + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + CHECK_TRUE(buildcc::env::get_task_state() == + buildcc::env::TaskState::FAILURE); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 1); + + fs::remove_all(cgen.GetBinaryPath()); + } + + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); +} + +TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { + constexpr const char *const kGenName = "real_generator_remove_and_add"; + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.Build(); + + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); + + CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + CHECK_EQUAL(imap.at("id2").outputs.size(), 1); + } + + // Same, no change + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.Build(); + + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); + + CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + CHECK_EQUAL(imap.at("id2").outputs.size(), 1); + } + + // Map Removed + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + + cgen.Build(); + + buildcc::m::CustomGeneratorExpect_IdRemoved(1, &cgen); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 1); + auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + + CHECK_THROWS(std::out_of_range, imap.at("id2")); + } + + // Map Added Failure + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.Build(); + + buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, false); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 1); + auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + CHECK_THROWS(std::out_of_range, imap.at("id2")); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); + } + + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); + + // Map Added Success + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.Build(); + + buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); + + CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + CHECK_EQUAL(imap.at("id2").outputs.size(), 1); + } +} + +TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { + constexpr const char *const kGenName = "real_generator_update_failure"; + + { + buildcc::CustomGenerator cgen(kGenName, ""); + buildcc::env::save_file( + (cgen.GetBuildDir() / "dummy_main.c").string().c_str(), "", false); + buildcc::env::save_file( + (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); + + cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.Build(); + + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); + + CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + CHECK_EQUAL(imap.at("id2").outputs.size(), 1); + } + + buildcc::m::blocking_sleep(1); + + // Updated Input file Failure + UT_PRINT("Updated Input file: Failure\r\n"); + { + buildcc::CustomGenerator cgen(kGenName, ""); + buildcc::env::save_file( + (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); + + cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.Build(); + + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, false); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 1); + auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); + } + + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); +} + +TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { + constexpr const char *const kGenName = "real_generator_update_success"; + + { + buildcc::CustomGenerator cgen(kGenName, ""); + buildcc::env::save_file( + (cgen.GetBuildDir() / "dummy_main.c").string().c_str(), "", false); + buildcc::env::save_file( + (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); + + cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.Build(); + + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); + + CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + CHECK_EQUAL(imap.at("id2").outputs.size(), 1); + } + + buildcc::m::blocking_sleep(1); + + // Updated Input file Success + UT_PRINT("Updated Input file: Success\r\n"); + { + buildcc::CustomGenerator cgen(kGenName, ""); + buildcc::env::save_file( + (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); + + std::uint64_t last_write_timestamp = static_cast( + fs::last_write_time(cgen.GetBuildDir() / "dummy_main.cpp") + .time_since_epoch() + .count()); + + cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.Build(); + + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + + CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id2").outputs.size(), 1); + + CHECK_EQUAL( + last_write_timestamp, + imap.at("id2").internal_inputs.begin()->GetLastWriteTimestamp()); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); + } + + // Updated Output file Success + UT_PRINT("Updated Output file: Success\r\n"); + { + buildcc::CustomGenerator cgen(kGenName, ""); + + cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/rename_dummy_main.o"}, RealGenerateCb); + cgen.Build(); + + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + + CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id2").outputs.size(), 1); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); + } +} + +int main(int ac, char **av) { + fs::remove_all(BUILD_DIR); + buildcc::Project::Init(fs::current_path() / "data", BUILD_DIR); + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/plugins/CMakeLists.txt b/buildcc/plugins/CMakeLists.txt index 0518831b..42e4700d 100644 --- a/buildcc/plugins/CMakeLists.txt +++ b/buildcc/plugins/CMakeLists.txt @@ -21,16 +21,17 @@ target_link_libraries(mock_plugins PUBLIC ) # Tests -add_executable(test_buildcc_find - test/test_buildcc_find.cpp -) -target_link_libraries(test_buildcc_find PRIVATE - mock_plugins -) +# Removed test_buildcc_find till it is not complete +# add_executable(test_buildcc_find +# test/test_buildcc_find.cpp +# ) +# target_link_libraries(test_buildcc_find PRIVATE +# mock_plugins +# ) -add_test(NAME test_buildcc_find COMMAND test_buildcc_find - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test -) +# add_test(NAME test_buildcc_find COMMAND test_buildcc_find +# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test +# ) endif() diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake index b3c996f8..01acf57f 100644 --- a/buildcc/schema/cmake/schema.cmake +++ b/buildcc/schema/cmake/schema.cmake @@ -1,6 +1,7 @@ # schema test if (${TESTING}) add_library(mock_schema STATIC + src/custom_generator_serialization.cpp src/generator_serialization.cpp src/target_serialization.cpp @@ -8,6 +9,7 @@ if (${TESTING}) include/schema/interface/serialization_interface.h include/schema/path.h + include/schema/custom_generator_serialization.h include/schema/generator_serialization.h include/schema/target_serialization.h ) @@ -30,10 +32,18 @@ if (${TESTING}) target_link_options(mock_schema PUBLIC ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS}) # Tests - add_dependencies(mock_schema fbs_to_header) + add_executable(test_custom_generator_serialization + test/test_custom_generator_serialization.cpp + ) + target_link_libraries(test_custom_generator_serialization PRIVATE mock_schema) + + add_test(NAME test_custom_generator_serialization COMMAND test_custom_generator_serialization + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test + ) endif() set(SCHEMA_SRCS + src/custom_generator_serialization.cpp src/generator_serialization.cpp src/target_serialization.cpp diff --git a/buildcc/schema/cmake/schema_generate.cmake b/buildcc/schema/cmake/schema_generate.cmake index cbbe4b23..4ba97f55 100644 --- a/buildcc/schema/cmake/schema_generate.cmake +++ b/buildcc/schema/cmake/schema_generate.cmake @@ -3,11 +3,13 @@ set(SCHEMA_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated CACHE PATH "Generate set(FBS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/path.fbs + ${CMAKE_CURRENT_SOURCE_DIR}/custom_generator.fbs ${CMAKE_CURRENT_SOURCE_DIR}/generator.fbs ${CMAKE_CURRENT_SOURCE_DIR}/target.fbs ) set(FBS_GEN_FILES ${SCHEMA_BUILD_DIR}/path_generated.h + ${SCHEMA_BUILD_DIR}/custom_generator_generated.h ${SCHEMA_BUILD_DIR}/generator_generated.h ${SCHEMA_BUILD_DIR}/target_generated.h ) diff --git a/buildcc/schema/custom_generator.fbs b/buildcc/schema/custom_generator.fbs new file mode 100644 index 00000000..8c5ce146 --- /dev/null +++ b/buildcc/schema/custom_generator.fbs @@ -0,0 +1,32 @@ +// Copyright 2021-2022 Niket Naidu. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +include "path.fbs"; + +namespace schema.internal; + +// Relational input and output files +table RelInputOutput { + id:string (key); + inputs:[Path]; + outputs:[string]; +} + +// Custom generator regenerate conditions +table CustomGenerator { + name:string (key); + rels:[RelInputOutput]; +} + +root_type CustomGenerator; diff --git a/buildcc/schema/include/schema/custom_generator_serialization.h b/buildcc/schema/include/schema/custom_generator_serialization.h new file mode 100644 index 00000000..0b440d3d --- /dev/null +++ b/buildcc/schema/include/schema/custom_generator_serialization.h @@ -0,0 +1,61 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCHEMA_CUSTOM_GENERATOR_SERIALIZATION_H_ +#define SCHEMA_CUSTOM_GENERATOR_SERIALIZATION_H_ + +#include +#include +#include + +#include "schema/path.h" + +#include "schema/interface/serialization_interface.h" + +namespace buildcc::internal { + +struct RelInputOutputSchema { + path_unordered_set internal_inputs; + fs_unordered_set outputs; +}; + +struct CustomGeneratorSchema { + std::string name; + std::unordered_map internal_rels_map; +}; + +class CustomGeneratorSerialization : public SerializationInterface { +public: + CustomGeneratorSerialization(const fs::path &serialized_file) + : SerializationInterface(serialized_file) {} + + void UpdateStore(const CustomGeneratorSchema &store) { store_ = store; } + const CustomGeneratorSchema &GetLoad() const { return load_; } + const CustomGeneratorSchema &GetStore() const { return store_; } + +private: + bool Verify(const std::string &serialized_data) override; + bool Load(const std::string &serialized_data) override; + bool Store(const fs::path &absolute_serialized_file) override; + +private: + CustomGeneratorSchema load_; + CustomGeneratorSchema store_; +}; + +} // namespace buildcc::internal + +#endif diff --git a/buildcc/schema/src/custom_generator_serialization.cpp b/buildcc/schema/src/custom_generator_serialization.cpp new file mode 100644 index 00000000..49eac4e3 --- /dev/null +++ b/buildcc/schema/src/custom_generator_serialization.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "schema/custom_generator_serialization.h" + +// Third party +#include "flatbuffers/flatbuffers.h" + +// Private +#include "schema/private/schema_util.h" + +// Schema generated +#include "custom_generator_generated.h" + +namespace buildcc::internal { + +// PRIVATE + +bool CustomGeneratorSerialization::Verify(const std::string &serialized_data) { + flatbuffers::Verifier verifier((const uint8_t *)serialized_data.c_str(), + serialized_data.length()); + return fbs::VerifyCustomGeneratorBuffer(verifier); +} + +bool CustomGeneratorSerialization::Load(const std::string &serialized_data) { + const auto *custom_generator = + fbs::GetCustomGenerator((const void *)serialized_data.c_str()); + // Verified, does not need a nullptr check + + const auto *fbs_rels = custom_generator->rels(); + if (fbs_rels == nullptr) { + return false; + } + + // rel_io->id is a required parameter, hence rel_io cannot be nullptr + for (const auto *rel_io : *fbs_rels) { + RelInputOutputSchema schema; + extract_path(rel_io->inputs(), schema.internal_inputs); + extract(rel_io->outputs(), schema.outputs); + load_.internal_rels_map.emplace(rel_io->id()->c_str(), std::move(schema)); + } + return true; +} + +bool CustomGeneratorSerialization::Store( + const fs::path &absolute_serialized_file) { + flatbuffers::FlatBufferBuilder builder; + + std::vector> fbs_rels; + for (const auto &rel_miter : store_.internal_rels_map) { + const auto &id = rel_miter.first; + const auto &rel_io = rel_miter.second; + auto fbs_internal_inputs = + internal::create_fbs_vector_path(builder, rel_io.internal_inputs); + auto fbs_outputs = + internal::create_fbs_vector_string(builder, rel_io.outputs); + auto fbs_rel = fbs::CreateRelInputOutputDirect( + builder, id.c_str(), &fbs_internal_inputs, &fbs_outputs); + fbs_rels.push_back(fbs_rel); + } + + auto fbs_generator = + fbs::CreateCustomGeneratorDirect(builder, store_.name.c_str(), &fbs_rels); + fbs::FinishCustomGeneratorBuffer(builder, fbs_generator); + + return env::save_file(path_as_string(absolute_serialized_file).c_str(), + (const char *)builder.GetBufferPointer(), + builder.GetSize(), true); +} + +} // namespace buildcc::internal diff --git a/buildcc/schema/test/.gitignore b/buildcc/schema/test/.gitignore new file mode 100644 index 00000000..a8a0dcec --- /dev/null +++ b/buildcc/schema/test/.gitignore @@ -0,0 +1 @@ +*.bin diff --git a/buildcc/schema/test/dump/.gitkeep b/buildcc/schema/test/dump/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/schema/test/test_custom_generator_serialization.cpp b/buildcc/schema/test/test_custom_generator_serialization.cpp new file mode 100644 index 00000000..1d69366c --- /dev/null +++ b/buildcc/schema/test/test_custom_generator_serialization.cpp @@ -0,0 +1,83 @@ +#include "schema/custom_generator_serialization.h" + +#include "schema/private/schema_util.h" + +#include "flatbuffers/flatbuffers.h" + +#include "custom_generator_generated.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(CustomGeneratorSerializationTestGroup) +{ + void teardown() { + mock().clear(); + } +}; +// clang-format on + +TEST(CustomGeneratorSerializationTestGroup, FormatEmptyCheck) { + buildcc::internal::CustomGeneratorSerialization serialization( + "dump/FormatEmptyCheck.bin"); + + { + flatbuffers::FlatBufferBuilder builder; + // Entire std::vector is nullptr + auto fbs_generator = + schema::internal::CreateCustomGeneratorDirect(builder, "", nullptr); + schema::internal::FinishCustomGeneratorBuffer(builder, fbs_generator); + + CHECK_TRUE(buildcc::env::save_file( + serialization.GetSerializedFile().string().c_str(), + (const char *)builder.GetBufferPointer(), builder.GetSize(), true)); + + CHECK_FALSE(serialization.LoadFromFile()); + + fs::remove_all(serialization.GetSerializedFile()); + } + + { + flatbuffers::FlatBufferBuilder builder; + // RelInputOutput in nullptr + auto rel_io = schema::internal::CreateRelInputOutputDirect(builder, ""); + std::vector v{rel_io}; + auto fbs_generator = + schema::internal::CreateCustomGeneratorDirect(builder, "", &v); + schema::internal::FinishCustomGeneratorBuffer(builder, fbs_generator); + + CHECK_TRUE(buildcc::env::save_file( + serialization.GetSerializedFile().string().c_str(), + (const char *)builder.GetBufferPointer(), builder.GetSize(), true)); + + CHECK_TRUE(serialization.LoadFromFile()); + + fs::remove_all(serialization.GetSerializedFile()); + } +} + +TEST(CustomGeneratorSerializationTestGroup, EmptyFile_Failure) { + { + buildcc::internal::CustomGeneratorSerialization serialization( + "dump/empty_file.bin"); + CHECK_FALSE(serialization.LoadFromFile()); + } + + { + buildcc::internal::CustomGeneratorSerialization serialization( + "dump/empty_file.bin"); + char data[] = {0}; + buildcc::env::save_file(serialization.GetSerializedFile().string().c_str(), + (const char *)data, 1, true); + CHECK_FALSE(serialization.LoadFromFile()); + } +} + +int main(int ac, char **av) { + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/toolchains/CMakeLists.txt b/buildcc/toolchains/CMakeLists.txt index 4bb1a8c2..b1380fcd 100644 --- a/buildcc/toolchains/CMakeLists.txt +++ b/buildcc/toolchains/CMakeLists.txt @@ -37,7 +37,7 @@ if (${TESTING}) ${TEST_LINK_LIBS} ) - add_executable(test_toolchain_specialized test/test_toolchain_specialized) + add_executable(test_toolchain_specialized test/test_toolchain_specialized.cpp) target_link_libraries(test_toolchain_specialized PRIVATE mock_toolchain_specialized) add_test(NAME test_toolchain_specialized COMMAND test_toolchain_specialized) From a0dc3ace833aee817553c090b7acbf085a969c26 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 14 May 2022 04:19:37 -0700 Subject: [PATCH 20/35] Create FileGenerator with CustomGenerator (#213) - FileGenerator created using CustomGenerator - Generator removed and renamed to FileGenerator --- bootstrap/include/bootstrap/build_buildcc.h | 8 +- bootstrap/main.buildcc.cpp | 2 +- bootstrap/src/build_buildcc.cpp | 10 +- buildcc/lib/args/include/args/register.h | 66 +++----- buildcc/lib/args/mock/tasks.cpp | 8 +- buildcc/lib/args/src/tasks.cpp | 4 +- buildcc/lib/target/cmake/mock_target.cmake | 5 - buildcc/lib/target/cmake/target.cmake | 3 - .../target/include/target/custom_generator.h | 64 +++++-- buildcc/lib/target/include/target/generator.h | 99 ++--------- buildcc/lib/target/mock/expect_generator.h | 23 --- .../target/mock/generator/recheck_states.cpp | 59 ------- buildcc/lib/target/mock/generator/runner.cpp | 13 -- .../src/custom_generator/custom_generator.cpp | 110 +++++++----- .../lib/target/src/generator/generator.cpp | 158 ++++++++++-------- .../target/src/generator/recheck_states.cpp | 28 ---- buildcc/lib/target/src/generator/task.cpp | 125 -------------- .../test/target/test_custom_generator.cpp | 141 ++++++++++++---- .../lib/target/test/target/test_generator.cpp | 129 ++++++-------- buildcc/schema/cmake/schema.cmake | 23 ++- buildcc/schema/cmake/schema_generate.cmake | 2 - buildcc/schema/custom_generator.fbs | 5 +- buildcc/schema/generator.fbs | 27 --- .../schema/custom_generator_serialization.h | 5 +- .../include/schema/generator_serialization.h | 58 ------- .../include/schema/private/schema_util.h | 11 ++ .../src/custom_generator_serialization.cpp | 41 ++--- .../schema/src/generator_serialization.cpp | 71 -------- .../test_custom_generator_serialization.cpp | 4 +- example/hybrid/dep_chaining/build.cpp | 20 +-- 30 files changed, 480 insertions(+), 842 deletions(-) delete mode 100644 buildcc/lib/target/mock/expect_generator.h delete mode 100644 buildcc/lib/target/mock/generator/recheck_states.cpp delete mode 100644 buildcc/lib/target/mock/generator/runner.cpp delete mode 100644 buildcc/lib/target/src/generator/recheck_states.cpp delete mode 100644 buildcc/lib/target/src/generator/task.cpp delete mode 100644 buildcc/schema/generator.fbs delete mode 100644 buildcc/schema/include/schema/generator_serialization.h delete mode 100644 buildcc/schema/src/generator_serialization.cpp diff --git a/bootstrap/include/bootstrap/build_buildcc.h b/bootstrap/include/bootstrap/build_buildcc.h index ccfe2602..e8c55804 100644 --- a/bootstrap/include/bootstrap/build_buildcc.h +++ b/bootstrap/include/bootstrap/build_buildcc.h @@ -28,9 +28,9 @@ namespace buildcc { -void schema_gen_cb(BaseGenerator &generator, const BaseTarget &flatc_exe); +void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe); -void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, +void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, const TargetInfo &flatbuffers_ho, const TargetInfo &fmt_ho, const TargetInfo &spdlog_ho, const TargetInfo &cli11_ho, const TargetInfo &taskflow_ho, const BaseTarget &tpl); @@ -80,8 +80,8 @@ class BuildBuildCC { ExecutableTarget_generic &GetFlatc() { return storage_.Ref(kFlatcExeName); } - BaseGenerator &GetSchemaGen() { - return storage_.Ref(kSchemaGenName); + FileGenerator &GetSchemaGen() { + return storage_.Ref(kSchemaGenName); } TargetInfo &GetFlatbuffersHo() { return storage_.Ref(kFlatbuffersHoName); diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index 4e8738fd..4701d5d6 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -49,7 +49,7 @@ int main(int argc, char **argv) { ExecutableTarget_generic buildcc_hybrid_simple_example( "buildcc_hybrid_simple_example", toolchain, "example/hybrid/simple"); Reg::Toolchain(custom_toolchain_arg.state) - .Func([&]() { toolchain.Verify(); }) + // .Func([&]() { toolchain.Verify(); }) .BuildPackage(buildcc) .Build(hybrid_simple_example_cb, buildcc_hybrid_simple_example, buildcc_lib) diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index cae0ad44..a42ca748 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -18,16 +18,14 @@ namespace buildcc { -void schema_gen_cb(BaseGenerator &generator, const BaseTarget &flatc_exe) { +void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe) { generator.AddInput("{gen_root_dir}/path.fbs", "path_fbs"); generator.AddInput("{gen_root_dir}/custom_generator.fbs", "custom_generator_fbs"); - generator.AddInput("{gen_root_dir}/generator.fbs", "generator_fbs"); generator.AddInput("{gen_root_dir}/target.fbs", "target_fbs"); generator.AddOutput("{gen_build_dir}/path_generated.h"); generator.AddOutput("{gen_build_dir}/custom_generator_generated.h"); - generator.AddOutput("{gen_build_dir}/generator_generated.h"); generator.AddOutput("{gen_build_dir}/target_generated.h"); generator.AddDefaultArguments({ @@ -36,12 +34,12 @@ void schema_gen_cb(BaseGenerator &generator, const BaseTarget &flatc_exe) { // generator.AddCommand("{flatc_compiler} --help"); generator.AddCommand( "{flatc_compiler} -o {gen_build_dir} -I {gen_root_dir} --gen-object-api " - "--cpp {path_fbs} {custom_generator_fbs} {generator_fbs} {target_fbs}"); + "--cpp {path_fbs} {custom_generator_fbs} {target_fbs}"); generator.Build(); } -void buildcc_cb(BaseTarget &target, const BaseGenerator &schema_gen, +void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, const TargetInfo &flatbuffers_ho, const TargetInfo &fmt_ho, const TargetInfo &spdlog_ho, const TargetInfo &cli11_ho, const TargetInfo &taskflow_ho, const BaseTarget &tpl) { @@ -201,7 +199,7 @@ void BuildBuildCC::Initialize() { env_.GetTargetBuildDir())); // Schema - (void)storage_.Add( + (void)storage_.Add( kSchemaGenName, kSchemaGenName, TargetEnv(env_.GetTargetRootDir() / "buildcc" / "schema", env_.GetTargetBuildDir() / toolchain_.GetName())); diff --git a/buildcc/lib/args/include/args/register.h b/buildcc/lib/args/include/args/register.h index 25b02b24..26b5795c 100644 --- a/buildcc/lib/args/include/args/register.h +++ b/buildcc/lib/args/include/args/register.h @@ -82,24 +82,17 @@ class Reg::Instance { } } - /** - * @brief Reg::Instance for Target to be built - */ - template - void Build(const C &build_cb, BaseTarget &target, Params &&...params) { - build_cb(target, std::forward(params)...); - tf::Task task = BuildTargetTask(target); - BuildStoreTask(target.GetUniqueId(), task); - } - - /** - * @brief Reg::Instance for Generator to be built - */ - template - void Build(const C &build_cb, BaseGenerator &generator, Params &&...params) { - build_cb(generator, std::forward(params)...); - tf::Task task = BuildGeneratorTask(generator); - BuildStoreTask(generator.GetUniqueId(), task); + template + void Build(const C &build_cb, T &builder, Params &&...params) { + constexpr bool is_supported_base = std::is_base_of_v || + std::is_base_of_v; + static_assert( + is_supported_base, + "Build only supports BaseTarget, CustomGenerator and derivatives"); + + build_cb(builder, std::forward(params)...); + tf::Task task = BuildTask(builder); + BuildStoreTask(builder.GetUniqueId(), task); } /** @@ -144,8 +137,8 @@ class Reg::Instance { private: private: // BuildTasks - tf::Task BuildTargetTask(BaseTarget &target); - tf::Task BuildGeneratorTask(BaseGenerator &generator); + tf::Task BuildTask(BaseTarget &target); + tf::Task BuildTask(CustomGenerator &generator); void BuildStoreTask(const std::string &unique_id, const tf::Task &task); private: @@ -167,11 +160,10 @@ class Reg::CallbackInstance { return *this; } - template - CallbackInstance &Build(const C &build_cb, BaseGenerator &generator, - Params &&...params) { + template + CallbackInstance &Build(const C &build_cb, T &builder, Params &&...params) { if (condition_) { - Ref().Build(build_cb, generator, std::forward(params)...); + Ref().Build(build_cb, builder, std::forward(params)...); }; return *this; } @@ -191,16 +183,14 @@ class Reg::ToolchainInstance { return *this; } - template - ToolchainInstance &Build(const C &build_cb, BaseGenerator &generator, - Params &&...params) { - return BuildInternal(build_cb, generator, std::forward(params)...); - } - template - ToolchainInstance &Build(const C &build_cb, BaseTarget &target, - Params &&...params) { - return BuildInternal(build_cb, target, std::forward(params)...); + template + ToolchainInstance &Build(const C &build_cb, T &builder, Params &&...params) { + if (condition_.build) { + Ref().Build(build_cb, builder, std::forward(params)...); + }; + return *this; } + // TODO, Update/Change this template ToolchainInstance &BuildPackage(P &package) { return Func([&]() { package.Setup(condition_); }); } @@ -209,16 +199,6 @@ class Reg::ToolchainInstance { ToolchainInstance &Test(const std::string &command, const BaseTarget &target, const TestConfig &config = TestConfig()); -private: - template - ToolchainInstance &BuildInternal(const C &build_cb, T &t, - Params &&...params) { - if (condition_.build) { - Ref().Build(build_cb, t, std::forward(params)...); - } - return *this; - } - private: ArgToolchainState condition_; }; diff --git a/buildcc/lib/args/mock/tasks.cpp b/buildcc/lib/args/mock/tasks.cpp index 40bc8eec..b1fbb92b 100644 --- a/buildcc/lib/args/mock/tasks.cpp +++ b/buildcc/lib/args/mock/tasks.cpp @@ -4,14 +4,12 @@ namespace buildcc { -tf::Task Reg::Instance::BuildTargetTask(BaseTarget &target) { +tf::Task Reg::Instance::BuildTask(BaseTarget &target) { mock().actualCall(fmt::format("BuildTask_{}", target.GetName()).c_str()); return build_tf_.placeholder().name(target.GetUniqueId()); } - -tf::Task Reg::Instance::BuildGeneratorTask(BaseGenerator &generator) { - mock().actualCall( - fmt::format("BuildGeneratorTask_{}", generator.GetName()).c_str()); +tf::Task Reg::Instance::BuildTask(CustomGenerator &generator) { + mock().actualCall(fmt::format("BuildTask_{}", generator.GetName()).c_str()); return build_tf_.placeholder().name(generator.GetUniqueId()); } diff --git a/buildcc/lib/args/src/tasks.cpp b/buildcc/lib/args/src/tasks.cpp index 054b8eed..170bf1d5 100644 --- a/buildcc/lib/args/src/tasks.cpp +++ b/buildcc/lib/args/src/tasks.cpp @@ -20,11 +20,11 @@ namespace buildcc { -tf::Task Reg::Instance::BuildTargetTask(BaseTarget &target) { +tf::Task Reg::Instance::BuildTask(BaseTarget &target) { return build_tf_.composed_of(target.GetTaskflow()).name(target.GetUniqueId()); } -tf::Task Reg::Instance::BuildGeneratorTask(BaseGenerator &generator) { +tf::Task Reg::Instance::BuildTask(CustomGenerator &generator) { return build_tf_.composed_of(generator.GetTaskflow()) .name(generator.GetUniqueId()); } diff --git a/buildcc/lib/target/cmake/mock_target.cmake b/buildcc/lib/target/cmake/mock_target.cmake index cf2b6bde..6b7928e4 100644 --- a/buildcc/lib/target/cmake/mock_target.cmake +++ b/buildcc/lib/target/cmake/mock_target.cmake @@ -4,11 +4,6 @@ add_library(mock_target STATIC mock/custom_generator/runner.cpp mock/custom_generator/recheck_states.cpp - # Generator mocks - src/generator/task.cpp - mock/generator/runner.cpp - mock/generator/recheck_states.cpp - # Target mocks src/target/tasks.cpp mock/target/runner.cpp diff --git a/buildcc/lib/target/cmake/target.cmake b/buildcc/lib/target/cmake/target.cmake index 931b1c46..b823b6cc 100644 --- a/buildcc/lib/target/cmake/target.cmake +++ b/buildcc/lib/target/cmake/target.cmake @@ -3,9 +3,6 @@ set(TARGET_SRCS src/custom_generator/recheck_states.cpp - src/generator/task.cpp - src/generator/recheck_states.cpp - src/target/recheck_states.cpp src/target/tasks.cpp ) diff --git a/buildcc/lib/target/include/target/custom_generator.h b/buildcc/lib/target/include/target/custom_generator.h index 8c10ee28..ddc01546 100644 --- a/buildcc/lib/target/include/target/custom_generator.h +++ b/buildcc/lib/target/include/target/custom_generator.h @@ -56,19 +56,48 @@ typedef std::function GenerateCb; typedef std::function &)> DependencyCb; // clang-format on -struct UserRelInputOutputSchema : internal::RelInputOutputSchema { +class CustomBlobHandler { +public: + bool CheckChanged(const std::vector &previous, + const std::vector ¤t) const { + env::assert_fatal( + Verify(previous), + "Stored blob is corrupted or User verification is incorrect"); + env::assert_fatal( + Verify(current), + "Current blob is corrupted or User verification is incorrect"); + return !IsEqual(previous, current); + }; + + std::vector GetSerializedData() { + auto serialized_data = Serialize(); + env::assert_fatal( + Verify(serialized_data), + "Serialized data is corrupted or Serialize function is incorrect"); + return serialized_data; + } + +private: + virtual bool Verify(const std::vector &serialized_data) const = 0; + virtual bool IsEqual(const std::vector &previous, + const std::vector ¤t) const = 0; + virtual std::vector Serialize() const = 0; +}; + +struct UserGenInfo : internal::GenInfo { fs_unordered_set inputs; GenerateCb generate_cb; + std::shared_ptr blob_handler{nullptr}; }; struct UserCustomGeneratorSchema : public internal::CustomGeneratorSchema { - std::unordered_map rels_map; + std::unordered_map gen_info_map; void ConvertToInternal() { - for (auto &r_miter : rels_map) { + for (auto &r_miter : gen_info_map) { r_miter.second.internal_inputs = path_schema_convert( r_miter.second.inputs, internal::Path::CreateExistingPath); - auto p = internal_rels_map.emplace(r_miter.first, r_miter.second); + auto p = internal_gen_info_map.emplace(r_miter.first, r_miter.second); env::assert_fatal(p.second, fmt::format("Could not save {}", r_miter.first)); } @@ -86,13 +115,17 @@ class CustomGenerator : public internal::BuilderInterface { virtual ~CustomGenerator() = default; CustomGenerator(const CustomGenerator &) = delete; - /** - * @brief Add default arguments for input, output and command requirements - * - * @param arguments Key-Value pair for arguments - */ + // From env::Command module, forwarding here + // TODO, Create a Mixin + void AddDefaultArgument(const std::string &identifier, + const std::string &pattern); void AddDefaultArguments( const std::unordered_map &arguments); + std::string Construct( + const std::string &pattern, + const std::unordered_map &arguments = {}); + const std::string & + GetValueByIdentifier(const std::string &file_identifier) const; /** * @brief Single Generator task for inputs->generate_cb->outputs @@ -105,7 +138,8 @@ class CustomGenerator : public internal::BuilderInterface { */ void AddGenInfo(const std::string &id, const fs_unordered_set &inputs, const fs_unordered_set &outputs, - const GenerateCb &generate_cb); + const GenerateCb &generate_cb, + std::shared_ptr blob_handler = nullptr); // Callbacks /** @@ -127,6 +161,7 @@ class CustomGenerator : public internal::BuilderInterface { void Build() override; // Getters + const std::string &GetName() const { return name_; } const fs::path &GetBinaryPath() const { return serialization_.GetSerializedFile(); } @@ -140,10 +175,9 @@ class CustomGenerator : public internal::BuilderInterface { template void TaskRunner(const std::string &id); void GenerateTask(); - void BuildGenerate(std::unordered_map - &gen_selected_map, - std::unordered_map - &dummy_gen_selected_map); + void BuildGenerate( + std::unordered_map &gen_selected_map, + std::unordered_map &dummy_gen_selected_map); // Recheck states void IdRemoved(); @@ -159,7 +193,7 @@ class CustomGenerator : public internal::BuilderInterface { UserCustomGeneratorSchema user_; std::mutex success_schema_mutex_; - std::unordered_map success_schema_; + std::unordered_map success_schema_; // Internal env::Command command_; diff --git a/buildcc/lib/target/include/target/generator.h b/buildcc/lib/target/include/target/generator.h index 3784e991..3e1c0068 100644 --- a/buildcc/lib/target/include/target/generator.h +++ b/buildcc/lib/target/include/target/generator.h @@ -17,51 +17,16 @@ #ifndef TARGET_GENERATOR_H_ #define TARGET_GENERATOR_H_ -#include -#include -#include -#include - -#include "taskflow/taskflow.hpp" - -#include "env/task_state.h" - -#include "env/command.h" - -#include "target/interface/builder_interface.h" - -#include "schema/generator_serialization.h" -#include "schema/path.h" - -#include "target/common/target_env.h" +#include "target/custom_generator.h" namespace buildcc { -// TODO, Make this private -struct UserGeneratorSchema : public internal::GeneratorSchema { - fs_unordered_set inputs; -}; - -class Generator : public internal::BuilderInterface { +class FileGenerator : public CustomGenerator { public: - Generator(const std::string &name, const TargetEnv &env, - bool parallel = false) - : name_(name), generator_root_dir_(env.GetTargetRootDir()), - generator_build_dir_(env.GetTargetBuildDir() / name), - serialization_(generator_build_dir_ / fmt::format("{}.bin", name)), - parallel_(parallel) { - Initialize(); - } - virtual ~Generator() = default; - Generator(const Generator &) = delete; - - /** - * @brief Add default arguments for input, output and command requirements - * - * @param arguments Key-Value pair for arguments - */ - void AddDefaultArguments( - const std::unordered_map &arguments); + FileGenerator(const std::string &name, const TargetEnv &env) + : CustomGenerator(name, env) {} + virtual ~FileGenerator() = default; + FileGenerator(const FileGenerator &) = delete; /** * @brief Add absolute input path pattern to generator @@ -98,59 +63,25 @@ class Generator : public internal::BuilderInterface { const std::unordered_map &arguments = {}); /** - * @brief Build Generator Tasks + * @brief Build FileGenerator Tasks * * Use `GetTaskflow` for the registered tasks */ void Build() override; - // Getter - const fs::path &GetBinaryPath() const { - return serialization_.GetSerializedFile(); - } - tf::Taskflow &GetTaskflow() { return tf_; } - - const std::string &GetName() const { return name_; } - env::TaskState GetTaskState() const { return task_state_; } - - const std::string & - GetValueByIdentifier(const std::string &file_identifier) const; - + // Restrict access to certain custom generator APIs private: - void Initialize(); - - void GenerateTask(); - void Convert(); - void BuildGenerate(); - - // Recheck states - void InputRemoved(); - void InputAdded(); - void InputUpdated(); - - void OutputChanged(); - void CommandChanged(); + using CustomGenerator::AddDependencyCb; + using CustomGenerator::AddGenInfo; + using CustomGenerator::Build; private: - // Constructor - std::string name_; - fs::path generator_root_dir_; - fs::path generator_build_dir_; - internal::GeneratorSerialization serialization_; - bool parallel_{false}; - - // Serialization - UserGeneratorSchema user_; - - // Internal - std::mutex task_state_mutex_; - env::TaskState task_state_{env::TaskState::SUCCESS}; - env::Command command_; - tf::Taskflow tf_; + // + internal::fs_unordered_set inputs_; + internal::fs_unordered_set outputs_; + std::vector commands_; }; -typedef Generator BaseGenerator; - } // namespace buildcc #endif diff --git a/buildcc/lib/target/mock/expect_generator.h b/buildcc/lib/target/mock/expect_generator.h deleted file mode 100644 index b41cd780..00000000 --- a/buildcc/lib/target/mock/expect_generator.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef TARGET_MOCK_EXPECT_GENERATOR_H_ -#define TARGET_MOCK_EXPECT_GENERATOR_H_ - -#include "target/generator.h" - -namespace buildcc::m { - -/** - * @brief Runs the generator using Taskflow with 1 thread - * CppUTest cannot mock with multiple threads - */ -void GeneratorRunner(Generator &generator); - -void GeneratorExpect_InputRemoved(unsigned int calls, Generator *generator); -void GeneratorExpect_InputAdded(unsigned int calls, Generator *generator); -void GeneratorExpect_InputUpdated(unsigned int calls, Generator *generator); - -void GeneratorExpect_OutputChanged(unsigned int calls, Generator *generator); -void GeneratorExpect_CommandChanged(unsigned int calls, Generator *generator); - -} // namespace buildcc::m - -#endif diff --git a/buildcc/lib/target/mock/generator/recheck_states.cpp b/buildcc/lib/target/mock/generator/recheck_states.cpp deleted file mode 100644 index ba424dae..00000000 --- a/buildcc/lib/target/mock/generator/recheck_states.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "target/generator.h" - -#include "expect_generator.h" - -#include "CppUTestExt/MockSupport.h" - -namespace buildcc { - -static constexpr const char *const INPUT_REMOVED_FUNCTION = - "Generator::InputRemoved"; -static constexpr const char *const INPUT_ADDED_FUNCTION = - "Generator::InputAdded"; -static constexpr const char *const INPUT_UPDATED_FUNCTION = - "Generator::InputUpdated"; - -static constexpr const char *const OUTPUT_CHANGED_FUNCTION = - "Generator::OutputChanged"; -static constexpr const char *const COMMAND_CHANGED_FUNCTION = - "Generator::CommandChanged"; - -void Generator::InputRemoved() { - mock().actualCall(INPUT_REMOVED_FUNCTION).onObject(this); -} -void Generator::InputAdded() { - mock().actualCall(INPUT_ADDED_FUNCTION).onObject(this); -} -void Generator::InputUpdated() { - mock().actualCall(INPUT_UPDATED_FUNCTION).onObject(this); -} - -void Generator::OutputChanged() { - mock().actualCall(OUTPUT_CHANGED_FUNCTION).onObject(this); -} -void Generator::CommandChanged() { - mock().actualCall(COMMAND_CHANGED_FUNCTION).onObject(this); -} - -namespace m { - -void GeneratorExpect_InputRemoved(unsigned int calls, Generator *generator) { - mock().expectNCalls(calls, INPUT_REMOVED_FUNCTION).onObject(generator); -} -void GeneratorExpect_InputAdded(unsigned int calls, Generator *generator) { - mock().expectNCalls(calls, INPUT_ADDED_FUNCTION).onObject(generator); -} -void GeneratorExpect_InputUpdated(unsigned int calls, Generator *generator) { - mock().expectNCalls(calls, INPUT_UPDATED_FUNCTION).onObject(generator); -} - -void GeneratorExpect_OutputChanged(unsigned int calls, Generator *generator) { - mock().expectNCalls(calls, OUTPUT_CHANGED_FUNCTION).onObject(generator); -} -void GeneratorExpect_CommandChanged(unsigned int calls, Generator *generator) { - mock().expectNCalls(calls, COMMAND_CHANGED_FUNCTION).onObject(generator); -} - -} // namespace m - -} // namespace buildcc diff --git a/buildcc/lib/target/mock/generator/runner.cpp b/buildcc/lib/target/mock/generator/runner.cpp deleted file mode 100644 index 3ca990e8..00000000 --- a/buildcc/lib/target/mock/generator/runner.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "target/generator.h" - -#include "expect_generator.h" - -namespace buildcc::m { - -void GeneratorRunner(Generator &generator) { - tf::Executor executor(1); - executor.run(generator.GetTaskflow()); - executor.wait_for_all(); -} - -} // namespace buildcc::m diff --git a/buildcc/lib/target/src/custom_generator/custom_generator.cpp b/buildcc/lib/target/src/custom_generator/custom_generator.cpp index 8d980c3f..fec70cab 100644 --- a/buildcc/lib/target/src/custom_generator/custom_generator.cpp +++ b/buildcc/lib/target/src/custom_generator/custom_generator.cpp @@ -27,23 +27,38 @@ constexpr const char *const kGenerateTaskName = "Generate"; namespace buildcc { +void CustomGenerator::AddDefaultArgument(const std::string &identifier, + const std::string &pattern) { + command_.AddDefaultArgument(identifier, command_.Construct(pattern)); +} + void CustomGenerator::AddDefaultArguments( const std::unordered_map &arguments) { for (const auto &arg_iter : arguments) { - command_.AddDefaultArgument(arg_iter.first, - command_.Construct(arg_iter.second)); + AddDefaultArgument(arg_iter.first, arg_iter.second); } } -void CustomGenerator::AddGenInfo(const std::string &id, - const fs_unordered_set &inputs, - const fs_unordered_set &outputs, - const GenerateCb &generate_cb) { - env::assert_fatal(user_.rels_map.find(id) == user_.rels_map.end(), +std::string CustomGenerator::Construct( + const std::string &pattern, + const std::unordered_map &arguments) { + return command_.Construct(pattern, arguments); +} + +const std::string &CustomGenerator::GetValueByIdentifier( + const std::string &file_identifier) const { + return command_.GetDefaultValueByKey(file_identifier); +} + +void CustomGenerator::AddGenInfo( + const std::string &id, const fs_unordered_set &inputs, + const fs_unordered_set &outputs, const GenerateCb &generate_cb, + std::shared_ptr blob_handler) { + env::assert_fatal(user_.gen_info_map.find(id) == user_.gen_info_map.end(), fmt::format("Duplicate id {} detected", id)); ASSERT_FATAL(generate_cb, "Invalid callback provided"); - UserRelInputOutputSchema schema; + UserGenInfo schema; for (const auto &i : inputs) { schema.inputs.emplace(command_.Construct(path_as_string(i))); } @@ -51,7 +66,8 @@ void CustomGenerator::AddGenInfo(const std::string &id, schema.outputs.emplace(command_.Construct(path_as_string(o))); } schema.generate_cb = generate_cb; - user_.rels_map.emplace(id, std::move(schema)); + schema.blob_handler = std::move(blob_handler); + user_.gen_info_map.emplace(id, std::move(schema)); } void CustomGenerator::AddDependencyCb(const DependencyCb &dependency_cb) { @@ -84,24 +100,25 @@ void CustomGenerator::Initialize() { } void CustomGenerator::BuildGenerate( - std::unordered_map &gen_selected_map, - std::unordered_map - &dummy_gen_selected_map) { + std::unordered_map &gen_selected_map, + std::unordered_map &dummy_gen_selected_map) { if (!serialization_.IsLoaded()) { - gen_selected_map = user_.rels_map; + gen_selected_map = user_.gen_info_map; dirty_ = true; } else { - // DONE, Conditionally select internal_rels depending on what has changed - const auto &prev_rels = serialization_.GetLoad().internal_rels_map; - const auto &curr_rels = user_.rels_map; - - // DONE, MAP REMOVED condition Check if prev_rels exists in curr_rels - // If prev_rels does not exist in curr_rels, has been removed from existing - // build - // We need this condition to only set the dirty_ flag - for (const auto &prev_miter : prev_rels) { + // DONE, Conditionally select internal_gen_info_map depending on what has + // changed + const auto &prev_gen_info_map = + serialization_.GetLoad().internal_gen_info_map; + const auto &curr_gen_info_map = user_.gen_info_map; + + // DONE, MAP REMOVED condition Check if prev_gen_info_map exists in + // curr_gen_info_map If prev_gen_info_map does not exist in + // curr_gen_info_map, has been removed from existing build We need this + // condition to only set the dirty_ flag + for (const auto &prev_miter : prev_gen_info_map) { const auto &id = prev_miter.first; - if (curr_rels.find(id) == curr_rels.end()) { + if (curr_gen_info_map.find(id) == curr_gen_info_map.end()) { // MAP REMOVED condition IdRemoved(); dirty_ = true; @@ -109,12 +126,12 @@ void CustomGenerator::BuildGenerate( } } - // DONE, MAP ADDED condition Check if curr_rels exists in prev_rels - // If curr_rels does not exist in prev_rels, has been added to existing - // build - for (const auto &curr_miter : curr_rels) { + // DONE, MAP ADDED condition Check if curr_gen_info_map exists in + // prev_gen_info_map If curr_gen_info_map does not exist in + // prev_gen_info_map, has been added to existing build + for (const auto &curr_miter : curr_gen_info_map) { const auto &id = curr_miter.first; - if (prev_rels.find(id) == prev_rels.end()) { + if (prev_gen_info_map.find(id) == prev_gen_info_map.end()) { // MAP ADDED condition IdAdded(); gen_selected_map.emplace(curr_miter.first, curr_miter.second); @@ -136,16 +153,15 @@ void CustomGenerator::GenerateTask() { } try { - std::unordered_map - selected_user_schema; - std::unordered_map - dummy_selected_user_schema; + std::unordered_map selected_user_schema; + std::unordered_map dummy_selected_user_schema; BuildGenerate(selected_user_schema, dummy_selected_user_schema); std::unordered_map task_map; // Create task for selected schema for (const auto &selected_miter : selected_user_schema) { const auto &id = selected_miter.first; + // const auto ¤t_info = selected_miter.second; tf::Task task = subflow .emplace([&]() { try { @@ -160,14 +176,10 @@ void CustomGenerator::GenerateTask() { for (auto &dummy_selected_miter : dummy_selected_user_schema) { const auto &id = dummy_selected_miter.first; - auto ¤t_info = dummy_selected_miter.second; + // const auto ¤t_info = dummy_selected_miter.second; tf::Task task = subflow .emplace([&]() { try { - user_.rels_map.at(id).internal_inputs = - internal::path_schema_convert( - current_info.inputs, - internal::Path::CreateExistingPath); TaskRunner(id); } catch (...) { env::set_task_state(env::TaskState::FAILURE); @@ -193,8 +205,8 @@ void CustomGenerator::GenerateTask() { // Store dummy_selected and successfully run schema if (dirty_) { UserCustomGeneratorSchema user_final_schema; - user_final_schema.rels_map.insert(success_schema_.begin(), - success_schema_.end()); + user_final_schema.gen_info_map.insert(success_schema_.begin(), + success_schema_.end()); user_final_schema.ConvertToInternal(); serialization_.UpdateStore(user_final_schema); @@ -211,17 +223,33 @@ void CustomGenerator::GenerateTask() { } template void CustomGenerator::TaskRunner(const std::string &id) { - const auto ¤t_info = user_.rels_map.at(id); + // Convert + { + auto ¤t_gen_info = user_.gen_info_map.at(id); + current_gen_info.internal_inputs = internal::path_schema_convert( + current_gen_info.inputs, internal::Path::CreateExistingPath); + current_gen_info.userblob = + current_gen_info.blob_handler != nullptr + ? current_gen_info.blob_handler->GetSerializedData() + : std::vector(); + } + + // Run + const auto ¤t_info = user_.gen_info_map.at(id); bool rerun = false; if constexpr (run) { rerun = true; } else { const auto &previous_info = - serialization_.GetLoad().internal_rels_map.at(id); + serialization_.GetLoad().internal_gen_info_map.at(id); rerun = internal::CheckPaths(previous_info.internal_inputs, current_info.internal_inputs) != internal::PathState::kNoChange || internal::CheckChanged(previous_info.outputs, current_info.outputs); + if (!rerun && current_info.blob_handler != nullptr) { + rerun = current_info.blob_handler->CheckChanged(previous_info.userblob, + current_info.userblob); + } } if (rerun) { diff --git a/buildcc/lib/target/src/generator/generator.cpp b/buildcc/lib/target/src/generator/generator.cpp index 5faab606..3437d2f5 100644 --- a/buildcc/lib/target/src/generator/generator.cpp +++ b/buildcc/lib/target/src/generator/generator.cpp @@ -18,100 +18,118 @@ #include +#include "flatbuffers/flexbuffers.h" + #include "env/assert_fatal.h" -namespace buildcc { +namespace { + +class GeneratorBlobHandler : public buildcc::CustomBlobHandler { +public: + explicit GeneratorBlobHandler(const std::vector &commands) + : commands_(commands) {} + +private: + const std::vector &commands_; + + bool Verify(const std::vector &serialized_data) const override { + auto flex_ref = flexbuffers::GetRoot(serialized_data); + if (!flex_ref.IsVector()) { + return false; + } + auto flex_vect = flex_ref.AsVector(); + for (size_t i = 0; i < flex_vect.size(); i++) { + if (!flex_vect[i].IsString()) { + return false; + } + } + return true; + } -void Generator::AddDefaultArguments( - const std::unordered_map &arguments) { - command_.AddDefaultArguments(arguments); -} + bool IsEqual(const std::vector &previous, + const std::vector ¤t) const override { + return Deserialize(previous) == Deserialize(current); + } + + std::vector Serialize() const override { + flexbuffers::Builder builder; + builder.Vector([&]() { + for (const auto &c : commands_) { + builder.Add(c); + } + }); + builder.Finish(); + return builder.GetBuffer(); + } + + // serialized_data has already been verified + static std::vector + Deserialize(const std::vector &serialized_data) { + std::vector deserialized; + auto flex_vect = flexbuffers::GetRoot(serialized_data).AsVector(); + for (size_t i = 0; i < flex_vect.size(); i++) { + deserialized.emplace_back(flex_vect[i].AsString().str()); + } + return deserialized; + } +}; + +} // namespace + +namespace buildcc { -void Generator::AddInput(const std::string &absolute_input_pattern, - const char *identifier) { - std::string absolute_input_string = - command_.Construct(absolute_input_pattern); +void FileGenerator::AddInput(const std::string &absolute_input_pattern, + const char *identifier) { + std::string absolute_input_string = Construct(absolute_input_pattern); const auto absolute_input_path = internal::Path::CreateNewPath(absolute_input_string); - user_.inputs.insert(absolute_input_path.GetPathname()); + inputs_.insert(absolute_input_path.GetPathname()); if (identifier != nullptr) { - command_.AddDefaultArgument(identifier, - absolute_input_path.GetPathAsString()); + AddDefaultArgument(identifier, absolute_input_path.GetPathAsString()); } } -void Generator::AddOutput(const std::string &absolute_output_pattern, - const char *identifier) { - std::string absolute_output_string = - command_.Construct(absolute_output_pattern); +void FileGenerator::AddOutput(const std::string &absolute_output_pattern, + const char *identifier) { + std::string absolute_output_string = Construct(absolute_output_pattern); const auto absolute_output_path = internal::Path::CreateNewPath(absolute_output_string); - user_.outputs.insert(absolute_output_path.GetPathname()); + outputs_.insert(absolute_output_path.GetPathname()); if (identifier != nullptr) { - command_.AddDefaultArgument(identifier, - absolute_output_path.GetPathAsString()); + AddDefaultArgument(identifier, absolute_output_path.GetPathAsString()); } } -void Generator::AddCommand( +void FileGenerator::AddCommand( const std::string &command_pattern, const std::unordered_map &arguments) { - std::string constructed_command = - command_.Construct(command_pattern, arguments); - user_.commands.emplace_back(std::move(constructed_command)); -} - -void Generator::Build() { - (void)serialization_.LoadFromFile(); - - GenerateTask(); + std::string constructed_command = Construct(command_pattern, arguments); + commands_.emplace_back(std::move(constructed_command)); } -const std::string & -Generator::GetValueByIdentifier(const std::string &file_identifier) const { - return command_.GetDefaultValueByKey(file_identifier); +void FileGenerator::Build() { + AddGenInfo( + "Generate", inputs_, outputs_, + [&](const CustomGeneratorContext &ctx) -> bool { + (void)ctx; + bool success = true; + for (const auto &c : commands_) { + bool executed = env::Command::Execute(c); + if (!executed) { + success = false; + env::log_critical(__FUNCTION__, + fmt::format("Failed to run command {}", c)); + break; + } + } + return success; + }, + std::make_shared(commands_)); + this->CustomGenerator::Build(); } // PRIVATE -void Generator::Initialize() { - // Checks - env::assert_fatal( - Project::IsInit(), - "Environment is not initialized. Use the buildcc::Project::Init API"); - - // - fs::create_directories(generator_build_dir_); - command_.AddDefaultArguments({ - {"gen_root_dir", path_as_string(generator_root_dir_)}, - {"gen_build_dir", path_as_string(generator_build_dir_)}, - }); - - // - unique_id_ = name_; - tf_.name(name_); -} - -void Generator::Convert() { - user_.internal_inputs = internal::path_schema_convert( - user_.inputs, internal::Path::CreateExistingPath); -} - -void Generator::BuildGenerate() { - if (!serialization_.IsLoaded()) { - dirty_ = true; - } else { - RecheckPaths( - serialization_.GetLoad().internal_inputs, user_.internal_inputs, - [&]() { InputRemoved(); }, [&]() { InputAdded(); }, - [&]() { InputUpdated(); }); - RecheckChanged(serialization_.GetLoad().outputs, user_.outputs, - [&]() { OutputChanged(); }); - RecheckChanged(serialization_.GetLoad().commands, user_.commands, - [&]() { CommandChanged(); }); - } -} - } // namespace buildcc diff --git a/buildcc/lib/target/src/generator/recheck_states.cpp b/buildcc/lib/target/src/generator/recheck_states.cpp deleted file mode 100644 index 5196c81f..00000000 --- a/buildcc/lib/target/src/generator/recheck_states.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/generator.h" - -namespace buildcc { - -void Generator::InputRemoved() {} -void Generator::InputAdded() {} -void Generator::InputUpdated() {} - -void Generator::OutputChanged() {} -void Generator::CommandChanged() {} - -} // namespace buildcc diff --git a/buildcc/lib/target/src/generator/task.cpp b/buildcc/lib/target/src/generator/task.cpp deleted file mode 100644 index 673e612e..00000000 --- a/buildcc/lib/target/src/generator/task.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/generator.h" - -#include "env/command.h" - -namespace { -constexpr const char *const kStartGeneratorTaskName = "Start Generator"; -constexpr const char *const kEndGeneratorTaskName = "End Generator"; - -constexpr const char *const kCommandTaskName = "Command"; -constexpr const char *const kGenerateTaskName = "Generate"; - -} // namespace - -namespace buildcc { - -void Generator::GenerateTask() { - tf::Task start_task = tf_.emplace([this]() { - switch (env::get_task_state()) { - case env::TaskState::SUCCESS: - try { - Convert(); - BuildGenerate(); - } catch (...) { - task_state_ = env::TaskState::FAILURE; - } - break; - default: - task_state_ = env::TaskState::FAILURE; - break; - } - return static_cast(task_state_); - }); - start_task.name(kStartGeneratorTaskName); - - tf::Task generate_task = tf_.emplace([&](tf::Subflow &subflow) { - auto run_command = [this](const std::string &command) { - try { - bool success = env::Command::Execute(command); - env::assert_fatal(success, fmt::format("{} failed", command)); - } catch (...) { - std::lock_guard guard(task_state_mutex_); - task_state_ = env::TaskState::FAILURE; - } - }; - - tf::Task command_task; - if (dirty_) { - if (parallel_) { - command_task = subflow.for_each(user_.commands.cbegin(), - user_.commands.cend(), run_command); - } else { - command_task = subflow.emplace([&, run_command]() { - for (const auto &command : user_.commands) { - run_command(command); - } - }); - } - } else { - command_task = subflow.placeholder(); - } - command_task.name(kCommandTaskName); - - // Graph Generation - for (const auto &i : user_.inputs) { - std::string name = - fmt::format("{}", i.lexically_relative(Project::GetRootDir())); - tf::Task task = subflow.placeholder().name(name); - task.precede(command_task); - } - - for (const auto &o : user_.outputs) { - std::string name = - fmt::format("{}", o.lexically_relative(Project::GetRootDir())); - tf::Task task = subflow.placeholder().name(name); - task.succeed(command_task); - } - }); - generate_task.name(kGenerateTaskName); - - tf::Task end_task = tf_.emplace([this]() { - // task_state_ != env::TaskState::SUCCESS - // We do not need to Store, leave the serialized store with the previous - // values - - // NOTE, Only store if the above state is marked dirty_ AND task_state_ == - // SUCCESS - if (task_state_ == env::TaskState::SUCCESS) { - if (dirty_) { - try { - serialization_.UpdateStore(user_); - env::assert_fatal(serialization_.StoreToFile(), - fmt::format("Store failed for {}", name_)); - } catch (...) { - task_state_ = env::TaskState::FAILURE; - } - } - } else { - // not SUCCESS state - env::set_task_state(task_state_); - } - }); - end_task.name(kEndGeneratorTaskName); - - // Dependencies - start_task.precede(generate_task, end_task); - generate_task.precede(end_task); -} - -} // namespace buildcc diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp index 27def93c..a7c6ea71 100644 --- a/buildcc/lib/target/test/target/test_custom_generator.cpp +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -4,9 +4,9 @@ #include "expect_custom_generator.h" #include "test_target_util.h" -// #include "test_target_util.h" -// #include "taskflow/taskflow.hpp" -// #include "env/util.h" +#include "flatbuffers/flexbuffers.h" + +#include // NOTE, Make sure all these includes are AFTER the system and header includes #include "CppUTest/CommandLineTestRunner.h" @@ -51,7 +51,7 @@ TEST(CustomGeneratorTestGroup, Basic) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_rels_map; + const auto &internal_map = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(internal_map.size(), 2); const auto &id1_info = internal_map.at("id1"); CHECK_EQUAL(id1_info.internal_inputs.size(), 1); @@ -81,7 +81,7 @@ TEST(CustomGeneratorTestGroup, Basic_Failure) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_rels_map; + const auto &internal_map = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(internal_map.size(), 1); } @@ -107,7 +107,7 @@ TEST(CustomGeneratorTestGroup, DefaultArgumentUsage) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_rels_map; + const auto &internal_map = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(internal_map.size(), 2); const auto &id1_info = internal_map.at("id1"); CHECK_EQUAL(id1_info.internal_inputs.size(), 1); @@ -207,7 +207,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_BasicCheck) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); } } @@ -244,7 +244,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); } } @@ -272,7 +272,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } @@ -291,7 +291,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } @@ -314,7 +314,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 0); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 0); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } @@ -341,7 +341,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } @@ -370,7 +370,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } @@ -403,7 +403,7 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); fs::remove_all(cgen.GetBinaryPath()); } @@ -427,7 +427,7 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); fs::remove_all(cgen.GetBinaryPath()); } @@ -454,8 +454,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); - auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + auto imap = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); @@ -477,8 +477,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); - auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + auto imap = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); @@ -500,8 +500,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 1); - auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); + auto imap = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id1").outputs.size(), 1); @@ -525,8 +525,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 1); - auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); + auto imap = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id1").outputs.size(), 1); CHECK_THROWS(std::out_of_range, imap.at("id2")); @@ -552,8 +552,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); - auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + auto imap = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); @@ -587,8 +587,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); - auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + auto imap = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); @@ -618,8 +618,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 1); - auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); + auto imap = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id1").outputs.size(), 1); @@ -654,8 +654,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); - auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + auto imap = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); @@ -690,8 +690,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); - auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + auto imap = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id1").outputs.size(), 1); @@ -723,8 +723,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_rels_map.size(), 2); - auto imap = serialization.GetLoad().internal_rels_map; + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + auto imap = serialization.GetLoad().internal_gen_info_map; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id1").outputs.size(), 1); @@ -735,6 +735,77 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { } } +class MyCustomBlobHandler : public buildcc::CustomBlobHandler { +public: + MyCustomBlobHandler(int32_t my_recheck_value) + : recheck_value(my_recheck_value) {} + +private: + int32_t recheck_value = 0; + +private: + bool Verify(const std::vector &serialized_data) const override { + return flexbuffers::GetRoot(serialized_data).IsInt(); + } + + bool IsEqual(const std::vector &previous, + const std::vector ¤t) const override { + return Deserialize(previous) == Deserialize(current); + } + + std::vector Serialize() const override { + flexbuffers::Builder builder; + builder.Add(recheck_value); + builder.Finish(); + return builder.GetBuffer(); + } + + // serialized_data has already been verified + int32_t Deserialize(const std::vector &serialized_data) const { + return flexbuffers::GetRoot(serialized_data).AsInt32(); + } +}; + +TEST(CustomGeneratorTestGroup, RealGenerate_BasicBlobRecheck) { + constexpr const char *const kGenName = "real_generator_basic_blob_recheck"; + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb, + std::make_shared(12)); + cgen.Build(); + + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); + } + + // Rebuild + { + buildcc::CustomGenerator cgen(kGenName, ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, + {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb, + std::make_shared(200)); + cgen.Build(); + + mock().expectOneCall("RealGenerateCb"); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::m::CustomGeneratorRunner(cgen); + + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); + } + + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); +} + int main(int ac, char **av) { fs::remove_all(BUILD_DIR); buildcc::Project::Init(fs::current_path() / "data", BUILD_DIR); diff --git a/buildcc/lib/target/test/target/test_generator.cpp b/buildcc/lib/target/test/target/test_generator.cpp index dc7b6375..62c8b722 100644 --- a/buildcc/lib/target/test/target/test_generator.cpp +++ b/buildcc/lib/target/test/target/test_generator.cpp @@ -1,7 +1,7 @@ #include "target/generator.h" #include "expect_command.h" -#include "expect_generator.h" +#include "expect_custom_generator.h" #include "test_target_util.h" #include "taskflow/taskflow.hpp" @@ -19,6 +19,7 @@ TEST_GROUP(GeneratorTestGroup) { void teardown() { + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); mock().clear(); } }; @@ -28,7 +29,7 @@ fs::path BUILD_DIR = fs::current_path() / "intermediate" / "generator"; TEST(GeneratorTestGroup, Generator_Build) { constexpr const char *const NAME = "Build"; - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddDefaultArguments({ {"compiler", "gcc"}, @@ -41,34 +42,14 @@ TEST(GeneratorTestGroup, Generator_Build) { buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); - - mock().checkExpectations(); -} - -TEST(GeneratorTestGroup, Generator_BuildParallel) { - constexpr const char *const NAME = "BuildParallel"; - buildcc::Generator generator(NAME, "", true); - - generator.AddDefaultArguments({ - {"compiler", "gcc"}, - }); - - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); - - buildcc::env::m::CommandExpect_Execute(1, true); - generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); mock().checkExpectations(); } TEST(GeneratorTestGroup, Generator_Identifier) { constexpr const char *const NAME = "Identifier"; - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddDefaultArguments({ {"compiler", "gcc"}, @@ -80,7 +61,7 @@ TEST(GeneratorTestGroup, Generator_Identifier) { buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); mock().checkExpectations(); } @@ -88,7 +69,7 @@ TEST(GeneratorTestGroup, Generator_Identifier) { TEST(GeneratorTestGroup, Generator_Rebuild) { constexpr const char *const NAME = "Rebuild"; { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/dummy_main.c"); generator.AddOutput("{gen_build_dir}/dummy_main.exe"); generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " @@ -99,11 +80,11 @@ TEST(GeneratorTestGroup, Generator_Rebuild) { buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/dummy_main.c"); generator.AddOutput("{gen_build_dir}/dummy_main.exe"); generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " @@ -113,7 +94,7 @@ TEST(GeneratorTestGroup, Generator_Rebuild) { }); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } mock().checkExpectations(); @@ -123,7 +104,7 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Inputs) { constexpr const char *const NAME = "Rebuild_Inputs"; { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/new_source.cpp"); generator.AddOutput("{gen_build_dir}/new_source.exe"); generator.AddCommand("gcc -o {gen_build_dir}/new_source.exe " @@ -131,34 +112,34 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Inputs) { buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } // Removed { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddOutput("{gen_build_dir}/new_source.exe"); generator.AddCommand("gcc -o {gen_build_dir}/new_source.exe " "{gen_root_dir}/new_source.cpp"); - buildcc::m::GeneratorExpect_InputRemoved(1, &generator); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } // Added { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/new_source.cpp"); generator.AddOutput("{gen_build_dir}/new_source.cpp.exe"); generator.AddCommand("gcc -o {gen_build_dir}/new_source.cpp.exe " "{gen_root_dir}/new_source.cpp"); - buildcc::m::GeneratorExpect_InputAdded(1, &generator); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } buildcc::m::blocking_sleep(1); @@ -169,15 +150,15 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Inputs) { // Updated { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/new_source.cpp"); generator.AddOutput("{gen_build_dir}/new_source.cpp.exe"); generator.AddCommand("gcc -o {gen_build_dir}/new_source.cpp.exe " "{gen_root_dir}/new_source.cpp"); - buildcc::m::GeneratorExpect_InputUpdated(1, &generator); + buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } mock().checkExpectations(); @@ -186,7 +167,7 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Inputs) { TEST(GeneratorTestGroup, Generator_Rebuild_Outputs) { constexpr const char *const NAME = "Rebuild_Outputs"; { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/dummy_main.c"); generator.AddOutput("{gen_build_dir}/dummy_main.exe"); generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " @@ -197,11 +178,11 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Outputs) { buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/dummy_main.c"); generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " "{gen_root_dir}/dummy_main.c", @@ -209,14 +190,13 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Outputs) { {"compiler", "gcc"}, }); - buildcc::m::GeneratorExpect_OutputChanged(1, &generator); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/dummy_main.c"); generator.AddOutput("{gen_build_dir}/dummy_main.exe"); generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " @@ -225,10 +205,9 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Outputs) { {"compiler", "gcc"}, }); - buildcc::m::GeneratorExpect_OutputChanged(1, &generator); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } mock().checkExpectations(); @@ -237,7 +216,7 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Outputs) { TEST(GeneratorTestGroup, Generator_Rebuild_Commands) { constexpr const char *const NAME = "Rebuild_Commands"; { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/dummy_main.c"); generator.AddOutput("{gen_build_dir}/dummy_main.exe"); generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " @@ -248,11 +227,11 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Commands) { buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/dummy_main.c"); generator.AddOutput("{gen_build_dir}/dummy_main.exe"); generator.AddCommand("{compiler} {gen_root_dir}/dummy_main.c", @@ -260,23 +239,21 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Commands) { {"compiler", "gcc"}, }); - buildcc::m::GeneratorExpect_CommandChanged(1, &generator); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } { - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddInput("{gen_root_dir}/dummy_main.c"); generator.AddOutput("{gen_build_dir}/dummy_main.exe"); generator.AddCommand("gcc -o {gen_build_dir}/dummy_main.exe " "{gen_root_dir}/dummy_main.c"); - buildcc::m::GeneratorExpect_CommandChanged(1, &generator); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } mock().checkExpectations(); @@ -284,7 +261,7 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Commands) { TEST(GeneratorTestGroup, Generator_AddDefaultArguments) { constexpr const char *const NAME = "AddDefaultArgument"; - buildcc::Generator generator(NAME, ""); + buildcc::FileGenerator generator(NAME, ""); generator.AddDefaultArguments({ {"key", "value"}, @@ -300,7 +277,7 @@ TEST(GeneratorTestGroup, Generator_FailedEnvTaskState) { buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE); constexpr const char *const NAME = "FailedEnvTaskState"; - buildcc::Generator generator(NAME, "", true); + buildcc::FileGenerator generator(NAME, ""); generator.AddDefaultArguments({ {"compiler", "gcc"}, @@ -312,7 +289,7 @@ TEST(GeneratorTestGroup, Generator_FailedEnvTaskState) { "{gen_root_dir}/dummy_main.c"); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); mock().checkExpectations(); @@ -321,7 +298,7 @@ TEST(GeneratorTestGroup, Generator_FailedEnvTaskState) { TEST(GeneratorTestGroup, Generator_FailedGenerateConvert) { constexpr const char *const NAME = "FailedGenerateConvert"; - buildcc::Generator generator(NAME, "", false); + buildcc::FileGenerator generator(NAME, ""); generator.AddDefaultArguments({ {"compiler", "gcc"}, @@ -333,7 +310,9 @@ TEST(GeneratorTestGroup, Generator_FailedGenerateConvert) { "{gen_root_dir}/dummy_main.c"); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); mock().checkExpectations(); @@ -342,7 +321,7 @@ TEST(GeneratorTestGroup, Generator_FailedGenerateConvert) { TEST(GeneratorTestGroup, Generator_FailedGenerateCommand) { constexpr const char *const NAME = "FailedGenerateCommand"; - buildcc::Generator generator(NAME, "", false); + buildcc::FileGenerator generator(NAME, ""); generator.AddDefaultArguments({ {"compiler", "gcc"}, @@ -355,7 +334,7 @@ TEST(GeneratorTestGroup, Generator_FailedGenerateCommand) { buildcc::env::m::CommandExpect_Execute(1, false); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); mock().checkExpectations(); @@ -366,7 +345,7 @@ TEST(GeneratorTestGroup, Generator_FailedStore) { constexpr const char *const NAME = "FailedStore"; const fs::path test_build_dir = buildcc::Project::GetBuildDir() / NAME; - buildcc::Generator generator(NAME, "", false); + buildcc::FileGenerator generator(NAME, ""); fs::remove_all(test_build_dir); generator.AddDefaultArguments({ @@ -380,9 +359,10 @@ TEST(GeneratorTestGroup, Generator_FailedStore) { buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); - CHECK(generator.GetTaskState() == buildcc::env::TaskState::FAILURE); + // CHECK(generator.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); mock().checkExpectations(); @@ -394,7 +374,7 @@ TEST(GeneratorTestGroup, FailedEnvTaskState_Rebuild) { constexpr const char *const NAME = "FailedEnvTaskState_Rebuild"; { - buildcc::Generator generator(NAME, "", true); + buildcc::FileGenerator generator(NAME, ""); generator.AddDefaultArguments({ {"compiler", "gcc"}, @@ -406,7 +386,7 @@ TEST(GeneratorTestGroup, FailedEnvTaskState_Rebuild) { "{gen_root_dir}/dummy_main.c"); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } // reset @@ -414,7 +394,7 @@ TEST(GeneratorTestGroup, FailedEnvTaskState_Rebuild) { // rebuild { - buildcc::Generator generator(NAME, "", true); + buildcc::FileGenerator generator(NAME, ""); generator.AddDefaultArguments({ {"compiler", "gcc"}, @@ -427,7 +407,7 @@ TEST(GeneratorTestGroup, FailedEnvTaskState_Rebuild) { generator.Build(); buildcc::env::m::CommandExpect_Execute(1, true); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } mock().checkExpectations(); @@ -437,7 +417,7 @@ TEST(GeneratorTestGroup, FailedGenerateCommand_Rebuild) { constexpr const char *const NAME = "FailedGenerateCommand_Rebuild"; { - buildcc::Generator generator(NAME, "", false); + buildcc::FileGenerator generator(NAME, ""); generator.AddDefaultArguments({ {"compiler", "gcc"}, @@ -450,7 +430,7 @@ TEST(GeneratorTestGroup, FailedGenerateCommand_Rebuild) { buildcc::env::m::CommandExpect_Execute(1, false); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } // reset @@ -458,7 +438,7 @@ TEST(GeneratorTestGroup, FailedGenerateCommand_Rebuild) { // rebuild { - buildcc::Generator generator(NAME, "", false); + buildcc::FileGenerator generator(NAME, ""); generator.AddDefaultArguments({ {"compiler", "gcc"}, @@ -469,9 +449,10 @@ TEST(GeneratorTestGroup, FailedGenerateCommand_Rebuild) { generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " "{gen_root_dir}/dummy_main.c"); + buildcc::m::CustomGeneratorExpect_IdAdded(1, &generator); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); - buildcc::m::GeneratorRunner(generator); + buildcc::m::CustomGeneratorRunner(generator); } mock().checkExpectations(); diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake index 01acf57f..207c6abc 100644 --- a/buildcc/schema/cmake/schema.cmake +++ b/buildcc/schema/cmake/schema.cmake @@ -1,16 +1,15 @@ # schema test if (${TESTING}) add_library(mock_schema STATIC - src/custom_generator_serialization.cpp - src/generator_serialization.cpp - src/target_serialization.cpp - include/schema/private/schema_util.h include/schema/interface/serialization_interface.h include/schema/path.h + + src/custom_generator_serialization.cpp include/schema/custom_generator_serialization.h - include/schema/generator_serialization.h + + src/target_serialization.cpp include/schema/target_serialization.h ) target_include_directories(mock_schema PUBLIC @@ -43,15 +42,15 @@ if (${TESTING}) endif() set(SCHEMA_SRCS - src/custom_generator_serialization.cpp - src/generator_serialization.cpp - src/target_serialization.cpp - include/schema/private/schema_util.h include/schema/interface/serialization_interface.h include/schema/path.h - include/schema/generator_serialization.h + + src/custom_generator_serialization.cpp + include/schema/custom_generator_serialization.h + + src/target_serialization.cpp include/schema/target_serialization.h ) @@ -80,15 +79,13 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) ) target_link_libraries(schema PUBLIC env + flatbuffers ) target_include_directories(schema PRIVATE ${SCHEMA_BUILD_DIR} ) target_compile_options(schema PRIVATE ${BUILD_COMPILE_FLAGS}) target_link_options(schema PRIVATE ${BUILD_LINK_FLAGS}) - target_link_libraries(schema PRIVATE - flatbuffers - ) add_dependencies(schema fbs_to_header) endif() diff --git a/buildcc/schema/cmake/schema_generate.cmake b/buildcc/schema/cmake/schema_generate.cmake index 4ba97f55..9b6eadf5 100644 --- a/buildcc/schema/cmake/schema_generate.cmake +++ b/buildcc/schema/cmake/schema_generate.cmake @@ -4,13 +4,11 @@ set(SCHEMA_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated CACHE PATH "Generate set(FBS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/path.fbs ${CMAKE_CURRENT_SOURCE_DIR}/custom_generator.fbs - ${CMAKE_CURRENT_SOURCE_DIR}/generator.fbs ${CMAKE_CURRENT_SOURCE_DIR}/target.fbs ) set(FBS_GEN_FILES ${SCHEMA_BUILD_DIR}/path_generated.h ${SCHEMA_BUILD_DIR}/custom_generator_generated.h - ${SCHEMA_BUILD_DIR}/generator_generated.h ${SCHEMA_BUILD_DIR}/target_generated.h ) set(FBS_GEN_OPTIONS diff --git a/buildcc/schema/custom_generator.fbs b/buildcc/schema/custom_generator.fbs index 8c5ce146..3c23fd75 100644 --- a/buildcc/schema/custom_generator.fbs +++ b/buildcc/schema/custom_generator.fbs @@ -17,16 +17,17 @@ include "path.fbs"; namespace schema.internal; // Relational input and output files -table RelInputOutput { +table GenInfo { id:string (key); inputs:[Path]; outputs:[string]; + userblob:[ubyte]; } // Custom generator regenerate conditions table CustomGenerator { name:string (key); - rels:[RelInputOutput]; + info:[GenInfo]; } root_type CustomGenerator; diff --git a/buildcc/schema/generator.fbs b/buildcc/schema/generator.fbs deleted file mode 100644 index 08166702..00000000 --- a/buildcc/schema/generator.fbs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2021-2022 Niket Naidu. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -include "path.fbs"; - -namespace schema.internal; - -// Each generator consists of many relational files of [input] - [output] - [commands] -table Generator { - name:string (key); - inputs:[Path]; - outputs:[string]; - commands:[string]; -} - -root_type Generator; diff --git a/buildcc/schema/include/schema/custom_generator_serialization.h b/buildcc/schema/include/schema/custom_generator_serialization.h index 0b440d3d..5c51746e 100644 --- a/buildcc/schema/include/schema/custom_generator_serialization.h +++ b/buildcc/schema/include/schema/custom_generator_serialization.h @@ -27,14 +27,15 @@ namespace buildcc::internal { -struct RelInputOutputSchema { +struct GenInfo { path_unordered_set internal_inputs; fs_unordered_set outputs; + std::vector userblob; }; struct CustomGeneratorSchema { std::string name; - std::unordered_map internal_rels_map; + std::unordered_map internal_gen_info_map; }; class CustomGeneratorSerialization : public SerializationInterface { diff --git a/buildcc/schema/include/schema/generator_serialization.h b/buildcc/schema/include/schema/generator_serialization.h deleted file mode 100644 index 9ee77298..00000000 --- a/buildcc/schema/include/schema/generator_serialization.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SCHEMA_GENERATOR_SERIALIZATION_H_ -#define SCHEMA_GENERATOR_SERIALIZATION_H_ - -#include -#include -#include - -#include "schema/path.h" - -#include "schema/interface/serialization_interface.h" - -namespace buildcc::internal { - -struct GeneratorSchema { - std::string name; - path_unordered_set internal_inputs; - fs_unordered_set outputs; - std::vector commands; -}; - -class GeneratorSerialization : public SerializationInterface { -public: - GeneratorSerialization(const fs::path &serialized_file) - : SerializationInterface(serialized_file) {} - - void UpdateStore(const GeneratorSchema &store) { store_ = store; } - const GeneratorSchema &GetLoad() const { return load_; } - const GeneratorSchema &GetStore() const { return store_; } - -private: - bool Verify(const std::string &serialized_data) override; - bool Load(const std::string &serialized_data) override; - bool Store(const fs::path &absolute_serialized_file) override; - -private: - GeneratorSchema load_; - GeneratorSchema store_; -}; - -} // namespace buildcc::internal - -#endif diff --git a/buildcc/schema/include/schema/private/schema_util.h b/buildcc/schema/include/schema/private/schema_util.h index 2684c2f5..d69263fe 100644 --- a/buildcc/schema/include/schema/private/schema_util.h +++ b/buildcc/schema/include/schema/private/schema_util.h @@ -57,6 +57,17 @@ inline void extract_path( } } +inline void extract(const flatbuffers::Vector *fbs_data, + std::vector &out) { + if (fbs_data == nullptr) { + return; + } + + for (auto iter = fbs_data->begin(); iter != fbs_data->end(); iter++) { + out.push_back(*iter); + } +} + inline void extract(const flatbuffers::Vector> *fbs_paths, diff --git a/buildcc/schema/src/custom_generator_serialization.cpp b/buildcc/schema/src/custom_generator_serialization.cpp index 49eac4e3..e6b8e119 100644 --- a/buildcc/schema/src/custom_generator_serialization.cpp +++ b/buildcc/schema/src/custom_generator_serialization.cpp @@ -40,17 +40,19 @@ bool CustomGeneratorSerialization::Load(const std::string &serialized_data) { fbs::GetCustomGenerator((const void *)serialized_data.c_str()); // Verified, does not need a nullptr check - const auto *fbs_rels = custom_generator->rels(); - if (fbs_rels == nullptr) { + const auto *fbs_gen_info = custom_generator->info(); + if (fbs_gen_info == nullptr) { return false; } - // rel_io->id is a required parameter, hence rel_io cannot be nullptr - for (const auto *rel_io : *fbs_rels) { - RelInputOutputSchema schema; - extract_path(rel_io->inputs(), schema.internal_inputs); - extract(rel_io->outputs(), schema.outputs); - load_.internal_rels_map.emplace(rel_io->id()->c_str(), std::move(schema)); + // gen_info->id is a required parameter, hence gen_info cannot be nullptr + for (const auto *gen_info : *fbs_gen_info) { + GenInfo current_info; + extract_path(gen_info->inputs(), current_info.internal_inputs); + extract(gen_info->outputs(), current_info.outputs); + extract(gen_info->userblob(), current_info.userblob); + load_.internal_gen_info_map.emplace(gen_info->id()->c_str(), + std::move(current_info)); } return true; } @@ -59,21 +61,22 @@ bool CustomGeneratorSerialization::Store( const fs::path &absolute_serialized_file) { flatbuffers::FlatBufferBuilder builder; - std::vector> fbs_rels; - for (const auto &rel_miter : store_.internal_rels_map) { - const auto &id = rel_miter.first; - const auto &rel_io = rel_miter.second; + std::vector> fbs_gen_info; + for (const auto &gen_info_iter : store_.internal_gen_info_map) { + const auto &id = gen_info_iter.first; + const auto &gen_info = gen_info_iter.second; auto fbs_internal_inputs = - internal::create_fbs_vector_path(builder, rel_io.internal_inputs); + internal::create_fbs_vector_path(builder, gen_info.internal_inputs); auto fbs_outputs = - internal::create_fbs_vector_string(builder, rel_io.outputs); - auto fbs_rel = fbs::CreateRelInputOutputDirect( - builder, id.c_str(), &fbs_internal_inputs, &fbs_outputs); - fbs_rels.push_back(fbs_rel); + internal::create_fbs_vector_string(builder, gen_info.outputs); + auto fbs_current_info = + fbs::CreateGenInfoDirect(builder, id.c_str(), &fbs_internal_inputs, + &fbs_outputs, &gen_info.userblob); + fbs_gen_info.push_back(fbs_current_info); } - auto fbs_generator = - fbs::CreateCustomGeneratorDirect(builder, store_.name.c_str(), &fbs_rels); + auto fbs_generator = fbs::CreateCustomGeneratorDirect( + builder, store_.name.c_str(), &fbs_gen_info); fbs::FinishCustomGeneratorBuffer(builder, fbs_generator); return env::save_file(path_as_string(absolute_serialized_file).c_str(), diff --git a/buildcc/schema/src/generator_serialization.cpp b/buildcc/schema/src/generator_serialization.cpp deleted file mode 100644 index cb4370f0..00000000 --- a/buildcc/schema/src/generator_serialization.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "schema/generator_serialization.h" - -// Third party -#include "flatbuffers/flatbuffers.h" - -// Private -#include "schema/private/schema_util.h" - -// Schema generated -#include "generator_generated.h" - -namespace buildcc::internal { - -// PRIVATE - -bool GeneratorSerialization::Verify(const std::string &serialized_data) { - flatbuffers::Verifier verifier((const uint8_t *)serialized_data.c_str(), - serialized_data.length()); - return fbs::VerifyGeneratorBuffer(verifier); -} - -bool GeneratorSerialization::Load(const std::string &serialized_data) { - const auto *generator = - fbs::GetGenerator((const void *)serialized_data.c_str()); - if (generator == nullptr) { - return false; - } - - extract_path(generator->inputs(), load_.internal_inputs); - extract(generator->outputs(), load_.outputs); - extract(generator->commands(), load_.commands); - return true; -} - -bool GeneratorSerialization::Store(const fs::path &absolute_serialized_file) { - flatbuffers::FlatBufferBuilder builder; - - auto fbs_input_files = - internal::create_fbs_vector_path(builder, store_.internal_inputs); - auto fbs_output_files = - internal::create_fbs_vector_string(builder, store_.outputs); - auto fbs_commands = - internal::create_fbs_vector_string(builder, store_.commands); - - auto fbs_generator = - fbs::CreateGeneratorDirect(builder, store_.name.c_str(), &fbs_input_files, - &fbs_output_files, &fbs_commands); - fbs::FinishGeneratorBuffer(builder, fbs_generator); - - return env::save_file(path_as_string(absolute_serialized_file).c_str(), - (const char *)builder.GetBufferPointer(), - builder.GetSize(), true); -} - -} // namespace buildcc::internal diff --git a/buildcc/schema/test/test_custom_generator_serialization.cpp b/buildcc/schema/test/test_custom_generator_serialization.cpp index 1d69366c..909b980b 100644 --- a/buildcc/schema/test/test_custom_generator_serialization.cpp +++ b/buildcc/schema/test/test_custom_generator_serialization.cpp @@ -45,8 +45,8 @@ TEST(CustomGeneratorSerializationTestGroup, FormatEmptyCheck) { { flatbuffers::FlatBufferBuilder builder; // RelInputOutput in nullptr - auto rel_io = schema::internal::CreateRelInputOutputDirect(builder, ""); - std::vector v{rel_io}; + auto gen_info = schema::internal::CreateGenInfoDirect(builder, ""); + std::vector v{gen_info}; auto fbs_generator = schema::internal::CreateCustomGeneratorDirect(builder, "", &v); schema::internal::FinishCustomGeneratorBuffer(builder, fbs_generator); diff --git a/example/hybrid/dep_chaining/build.cpp b/example/hybrid/dep_chaining/build.cpp index 3baddfe0..906ecfe6 100644 --- a/example/hybrid/dep_chaining/build.cpp +++ b/example/hybrid/dep_chaining/build.cpp @@ -9,10 +9,10 @@ constexpr const char *const EXE = "build"; // Function Prototypes static void clean_cb(); static void cpp_target_cb(BaseTarget &cpptarget, - const BaseGenerator &cpp_generator); -static void c_target_cb(BaseTarget &ctarget, const BaseGenerator &c_generator); -static void cpp_generator_cb(BaseGenerator &generator); -static void c_generator_cb(BaseGenerator &generator); + const FileGenerator &cpp_generator); +static void c_target_cb(BaseTarget &ctarget, const FileGenerator &c_generator); +static void cpp_generator_cb(FileGenerator &generator); +static void c_generator_cb(FileGenerator &generator); int main(int argc, char **argv) { // Get arguments @@ -30,8 +30,8 @@ int main(int argc, char **argv) { Reg::Call(Args::Clean()).Func(clean_cb); // Generator - BaseGenerator cpp_generator("cpp_generator", ""); - BaseGenerator c_generator("c_generator", ""); + FileGenerator cpp_generator("cpp_generator", ""); + FileGenerator c_generator("c_generator", ""); Reg::Call() .Build(cpp_generator_cb, cpp_generator) .Build(c_generator_cb, c_generator); @@ -82,7 +82,7 @@ static void clean_cb() { } static void cpp_target_cb(BaseTarget &cpptarget, - const BaseGenerator &cpp_generator) { + const FileGenerator &cpp_generator) { const fs::path main_cpp = fs::path(cpp_generator.GetValueByIdentifier("main_cpp")) .lexically_relative(Project::GetRootDir()); @@ -90,21 +90,21 @@ static void cpp_target_cb(BaseTarget &cpptarget, cpptarget.Build(); } -static void c_target_cb(BaseTarget &ctarget, const BaseGenerator &c_generator) { +static void c_target_cb(BaseTarget &ctarget, const FileGenerator &c_generator) { const fs::path main_c = fs::path(c_generator.GetValueByIdentifier("main_c")) .lexically_relative(Project::GetRootDir()); ctarget.AddSource(main_c); ctarget.Build(); } -static void cpp_generator_cb(BaseGenerator &generator) { +static void cpp_generator_cb(FileGenerator &generator) { generator.AddOutput("{gen_build_dir}/main.cpp", "main_cpp"); generator.AddCommand("python3 {gen_root_dir}/python/gen.py --source_type cpp " "--destination {main_cpp}"); generator.Build(); } -static void c_generator_cb(BaseGenerator &generator) { +static void c_generator_cb(FileGenerator &generator) { generator.AddOutput("{gen_build_dir}/main.c", "main_c"); generator.AddCommand("python3 {gen_root_dir}/python/gen.py --source_type c " "--destination {main_c}"); From d952b6fb27a3c2cb133b5073d5f2b65938a331d3 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 15 May 2022 03:47:23 -0700 Subject: [PATCH 21/35] Template generator (#214) --- bootstrap/main.buildcc.cpp | 2 +- bootstrap/src/build_buildcc.cpp | 5 +- buildcc/buildcc.h | 3 +- buildcc/lib/args/include/args/register.h | 3 +- .../lib/target/cmake/common_target_src.cmake | 6 +- .../target/include/target/custom_generator.h | 22 ++--- .../target/{generator.h => file_generator.h} | 4 +- .../target/interface/builder_interface.h | 54 ++++------- .../include/target/template_generator.h | 58 +++++++++++ .../src/custom_generator/custom_generator.cpp | 34 ++++--- .../{generator.cpp => file_generator.cpp} | 15 +-- .../src/generator/template_generator.cpp | 77 +++++++++++++++ buildcc/lib/target/test/target/CMakeLists.txt | 16 ++- .../data/template/default_values.txt.in | 4 + .../target/data/template/hello_world.txt.in | 1 + .../test/target/test_custom_generator.cpp | 2 +- ..._generator.cpp => test_file_generator.cpp} | 56 +++++------ .../test/target/test_template_generator.cpp | 97 +++++++++++++++++++ .../include/schema/target_serialization.h | 2 +- buildcc/schema/include/schema/target_type.h | 1 + example/hybrid/dep_chaining/build.cpp | 7 +- 21 files changed, 353 insertions(+), 116 deletions(-) rename buildcc/lib/target/include/target/{generator.h => file_generator.h} (97%) create mode 100644 buildcc/lib/target/include/target/template_generator.h rename buildcc/lib/target/src/generator/{generator.cpp => file_generator.cpp} (89%) create mode 100644 buildcc/lib/target/src/generator/template_generator.cpp create mode 100644 buildcc/lib/target/test/target/data/template/default_values.txt.in create mode 100644 buildcc/lib/target/test/target/data/template/hello_world.txt.in rename buildcc/lib/target/test/target/{test_generator.cpp => test_file_generator.cpp} (91%) create mode 100644 buildcc/lib/target/test/target/test_template_generator.cpp diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index 4701d5d6..4e8738fd 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -49,7 +49,7 @@ int main(int argc, char **argv) { ExecutableTarget_generic buildcc_hybrid_simple_example( "buildcc_hybrid_simple_example", toolchain, "example/hybrid/simple"); Reg::Toolchain(custom_toolchain_arg.state) - // .Func([&]() { toolchain.Verify(); }) + .Func([&]() { toolchain.Verify(); }) .BuildPackage(buildcc) .Build(hybrid_simple_example_cb, buildcc_hybrid_simple_example, buildcc_lib) diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index a42ca748..8669dffc 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -28,7 +28,7 @@ void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe) { generator.AddOutput("{gen_build_dir}/custom_generator_generated.h"); generator.AddOutput("{gen_build_dir}/target_generated.h"); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"flatc_compiler", fmt::format("{}", flatc_exe.GetTargetPath())}, }); // generator.AddCommand("{flatc_compiler} --help"); @@ -45,8 +45,7 @@ void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, const TargetInfo &taskflow_ho, const BaseTarget &tpl) { // NOTE, Build as single lib target.AddIncludeDir("", true); - const std::string &schema_build_dir = - schema_gen.GetValueByIdentifier("gen_build_dir"); + const std::string &schema_build_dir = schema_gen.Get("gen_build_dir"); target.AddIncludeDirAbsolute(schema_build_dir, true); // ENV diff --git a/buildcc/buildcc.h b/buildcc/buildcc.h index e73bbffe..a48551cb 100644 --- a/buildcc/buildcc.h +++ b/buildcc/buildcc.h @@ -32,7 +32,8 @@ // Base #include "toolchain/toolchain.h" #include "target/custom_generator.h" -#include "target/generator.h" +#include "target/file_generator.h" +#include "target/template_generator.h" #include "target/target_info.h" #include "target/target.h" diff --git a/buildcc/lib/args/include/args/register.h b/buildcc/lib/args/include/args/register.h index 26b5795c..62013db4 100644 --- a/buildcc/lib/args/include/args/register.h +++ b/buildcc/lib/args/include/args/register.h @@ -22,7 +22,8 @@ #include "args.h" -#include "target/generator.h" +#include "target/custom_generator.h" +#include "target/file_generator.h" #include "target/target.h" #include "args/register/test_info.h" diff --git a/buildcc/lib/target/cmake/common_target_src.cmake b/buildcc/lib/target/cmake/common_target_src.cmake index 31ab0a03..130bda3f 100644 --- a/buildcc/lib/target/cmake/common_target_src.cmake +++ b/buildcc/lib/target/cmake/common_target_src.cmake @@ -36,8 +36,10 @@ set(COMMON_TARGET_SRCS # Generator src/custom_generator/custom_generator.cpp include/target/custom_generator.h - src/generator/generator.cpp - include/target/generator.h + src/generator/file_generator.cpp + include/target/file_generator.h + src/generator/template_generator.cpp + include/target/template_generator.h # Target Info src/target_info/target_info.cpp diff --git a/buildcc/lib/target/include/target/custom_generator.h b/buildcc/lib/target/include/target/custom_generator.h index ddc01546..76e64576 100644 --- a/buildcc/lib/target/include/target/custom_generator.h +++ b/buildcc/lib/target/include/target/custom_generator.h @@ -115,17 +115,12 @@ class CustomGenerator : public internal::BuilderInterface { virtual ~CustomGenerator() = default; CustomGenerator(const CustomGenerator &) = delete; - // From env::Command module, forwarding here - // TODO, Create a Mixin - void AddDefaultArgument(const std::string &identifier, - const std::string &pattern); - void AddDefaultArguments( - const std::unordered_map &arguments); - std::string Construct( - const std::string &pattern, - const std::unordered_map &arguments = {}); - const std::string & - GetValueByIdentifier(const std::string &file_identifier) const; + // TODO, Doc + void AddPattern(const std::string &identifier, const std::string &pattern); + + // TODO, Doc + void + AddPatterns(const std::unordered_map &pattern_map); /** * @brief Single Generator task for inputs->generate_cb->outputs @@ -168,6 +163,7 @@ class CustomGenerator : public internal::BuilderInterface { const fs::path &GetRootDir() const { return env_.GetTargetRootDir(); } const fs::path &GetBuildDir() const { return env_.GetTargetBuildDir(); } tf::Taskflow &GetTaskflow() { return tf_; } + const std::string &Get(const std::string &file_identifier) const; private: void Initialize(); @@ -184,6 +180,9 @@ class CustomGenerator : public internal::BuilderInterface { void IdAdded(); void IdUpdated(); +protected: + env::Command command_; + private: std::string name_; TargetEnv env_; @@ -196,7 +195,6 @@ class CustomGenerator : public internal::BuilderInterface { std::unordered_map success_schema_; // Internal - env::Command command_; tf::Taskflow tf_; // Callbacks diff --git a/buildcc/lib/target/include/target/generator.h b/buildcc/lib/target/include/target/file_generator.h similarity index 97% rename from buildcc/lib/target/include/target/generator.h rename to buildcc/lib/target/include/target/file_generator.h index 3e1c0068..08eb1d99 100644 --- a/buildcc/lib/target/include/target/generator.h +++ b/buildcc/lib/target/include/target/file_generator.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef TARGET_GENERATOR_H_ -#define TARGET_GENERATOR_H_ +#ifndef TARGET_FILE_GENERATOR_H_ +#define TARGET_FILE_GENERATOR_H_ #include "target/custom_generator.h" diff --git a/buildcc/lib/target/include/target/interface/builder_interface.h b/buildcc/lib/target/include/target/interface/builder_interface.h index 22fbb7ba..cfe40202 100644 --- a/buildcc/lib/target/include/target/interface/builder_interface.h +++ b/buildcc/lib/target/include/target/interface/builder_interface.h @@ -27,7 +27,7 @@ namespace buildcc::internal { -enum PathState { +enum class PathState { kNoChange, kRemoved, kAdded, @@ -69,14 +69,14 @@ inline PathState CheckPaths(const internal::path_unordered_set &previous_path, const bool added_cond = (find == previous_path.end()); if (added_cond) { dirty = true; - state = kAdded; + state = PathState::kAdded; } else { const bool updated_cond = (p.GetLastWriteTimestamp() > find->GetLastWriteTimestamp()); if (updated_cond) { dirty = true; - state = kUpdated; + state = PathState::kUpdated; } else { dirty = false; } @@ -110,7 +110,7 @@ class BuilderInterface { return; } - if (previous != current) { + if (CheckChanged(previous, current)) { callback(); dirty_ = true; } @@ -130,39 +130,25 @@ class BuilderInterface { return; } - // * Old path is removed - const bool removed = - std::any_of(previous_path.begin(), previous_path.end(), - [&](const internal::Path &p) { - return current_path.find(p) == current_path.end(); - }); - if (removed) { + auto path_state = CheckPaths(previous_path, current_path); + switch (path_state) { + case PathState::kRemoved: path_removed_cb(); dirty_ = true; - return; + break; + case PathState::kAdded: + path_added_cb(); + dirty_ = true; + break; + case PathState::kUpdated: + path_updated_cb(); + dirty_ = true; + break; + case PathState::kNoChange: + default: + dirty_ = false; + break; } - - dirty_ = std::any_of( - current_path.cbegin(), current_path.cend(), - [&](const internal::Path &p) -> bool { - bool dirty = false; - const auto find = previous_path.find(p); - const bool added_cond = (find == previous_path.end()); - if (added_cond) { - path_added_cb(); - dirty = true; - } else { - const bool updated_cond = - (p.GetLastWriteTimestamp() > find->GetLastWriteTimestamp()); - if (updated_cond) { - path_updated_cb(); - dirty = true; - } else { - dirty = false; - } - } - return dirty; - }); } protected: diff --git a/buildcc/lib/target/include/target/template_generator.h b/buildcc/lib/target/include/target/template_generator.h new file mode 100644 index 00000000..2d2061a5 --- /dev/null +++ b/buildcc/lib/target/include/target/template_generator.h @@ -0,0 +1,58 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TARGET_TEMPLATE_GENERATOR_H_ +#define TARGET_TEMPLATE_GENERATOR_H_ + +#include "target/custom_generator.h" + +namespace buildcc { + +class TemplateGenerator : public CustomGenerator { +public: + TemplateGenerator(const std::string &name, const TargetEnv &env) + : CustomGenerator(name, env) {} + + void AddTemplate(const fs::path &input_filename, + const fs::path &output_filename); + std::string Parse(const std::string &pattern); + + /** + * @brief Build FileGenerator Tasks + * + * Use `GetTaskflow` for the registered tasks + */ + void Build() override; + + // Restrict access to certain custom generator APIs +private: + using CustomGenerator::AddDependencyCb; + using CustomGenerator::AddGenInfo; + using CustomGenerator::Build; + +private: + struct TemplateInfo { + fs::path input; + fs::path output; + }; + +private: + std::vector template_infos_; +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/lib/target/src/custom_generator/custom_generator.cpp b/buildcc/lib/target/src/custom_generator/custom_generator.cpp index fec70cab..466d43dd 100644 --- a/buildcc/lib/target/src/custom_generator/custom_generator.cpp +++ b/buildcc/lib/target/src/custom_generator/custom_generator.cpp @@ -27,26 +27,20 @@ constexpr const char *const kGenerateTaskName = "Generate"; namespace buildcc { -void CustomGenerator::AddDefaultArgument(const std::string &identifier, - const std::string &pattern) { +void CustomGenerator::AddPattern(const std::string &identifier, + const std::string &pattern) { command_.AddDefaultArgument(identifier, command_.Construct(pattern)); } -void CustomGenerator::AddDefaultArguments( - const std::unordered_map &arguments) { - for (const auto &arg_iter : arguments) { - AddDefaultArgument(arg_iter.first, arg_iter.second); +void CustomGenerator::AddPatterns( + const std::unordered_map &pattern_map) { + for (const auto &arg_iter : pattern_map) { + AddPattern(arg_iter.first, arg_iter.second); } } -std::string CustomGenerator::Construct( - const std::string &pattern, - const std::unordered_map &arguments) { - return command_.Construct(pattern, arguments); -} - -const std::string &CustomGenerator::GetValueByIdentifier( - const std::string &file_identifier) const { +const std::string & +CustomGenerator::Get(const std::string &file_identifier) const { return command_.GetDefaultValueByKey(file_identifier); } @@ -60,10 +54,16 @@ void CustomGenerator::AddGenInfo( UserGenInfo schema; for (const auto &i : inputs) { - schema.inputs.emplace(command_.Construct(path_as_string(i))); + fs::path input = + internal::Path::CreateNewPath(command_.Construct(path_as_string(i))) + .GetPathname(); + schema.inputs.emplace(std::move(input)); } for (const auto &o : outputs) { - schema.outputs.emplace(command_.Construct(path_as_string(o))); + fs::path output = + internal::Path::CreateNewPath(command_.Construct(path_as_string(o))) + .GetPathname(); + schema.outputs.emplace(std::move(output)); } schema.generate_cb = generate_cb; schema.blob_handler = std::move(blob_handler); @@ -90,6 +90,8 @@ void CustomGenerator::Initialize() { // fs::create_directories(env_.GetTargetBuildDir()); command_.AddDefaultArguments({ + {"project_root_dir", path_as_string(Project::GetRootDir())}, + {"project_build_dir", path_as_string(Project::GetBuildDir())}, {"gen_root_dir", path_as_string(env_.GetTargetRootDir())}, {"gen_build_dir", path_as_string(env_.GetTargetBuildDir())}, }); diff --git a/buildcc/lib/target/src/generator/generator.cpp b/buildcc/lib/target/src/generator/file_generator.cpp similarity index 89% rename from buildcc/lib/target/src/generator/generator.cpp rename to buildcc/lib/target/src/generator/file_generator.cpp index 3437d2f5..ca94d9e2 100644 --- a/buildcc/lib/target/src/generator/generator.cpp +++ b/buildcc/lib/target/src/generator/file_generator.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "target/generator.h" +#include "target/file_generator.h" #include @@ -80,32 +80,35 @@ namespace buildcc { void FileGenerator::AddInput(const std::string &absolute_input_pattern, const char *identifier) { - std::string absolute_input_string = Construct(absolute_input_pattern); + std::string absolute_input_string = + command_.Construct(absolute_input_pattern); const auto absolute_input_path = internal::Path::CreateNewPath(absolute_input_string); inputs_.insert(absolute_input_path.GetPathname()); if (identifier != nullptr) { - AddDefaultArgument(identifier, absolute_input_path.GetPathAsString()); + AddPattern(identifier, absolute_input_path.GetPathAsString()); } } void FileGenerator::AddOutput(const std::string &absolute_output_pattern, const char *identifier) { - std::string absolute_output_string = Construct(absolute_output_pattern); + std::string absolute_output_string = + command_.Construct(absolute_output_pattern); const auto absolute_output_path = internal::Path::CreateNewPath(absolute_output_string); outputs_.insert(absolute_output_path.GetPathname()); if (identifier != nullptr) { - AddDefaultArgument(identifier, absolute_output_path.GetPathAsString()); + AddPattern(identifier, absolute_output_path.GetPathAsString()); } } void FileGenerator::AddCommand( const std::string &command_pattern, const std::unordered_map &arguments) { - std::string constructed_command = Construct(command_pattern, arguments); + std::string constructed_command = + command_.Construct(command_pattern, arguments); commands_.emplace_back(std::move(constructed_command)); } diff --git a/buildcc/lib/target/src/generator/template_generator.cpp b/buildcc/lib/target/src/generator/template_generator.cpp new file mode 100644 index 00000000..c99fc541 --- /dev/null +++ b/buildcc/lib/target/src/generator/template_generator.cpp @@ -0,0 +1,77 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "target/template_generator.h" + +#include "env/env.h" + +namespace { + +bool template_generate_cb(const buildcc::CustomGeneratorContext &ctx) { + std::string pattern_data; + const fs::path &input = *ctx.inputs.begin(); + const fs::path &output = *ctx.outputs.begin(); + + bool success = + buildcc::env::load_file(input.string().c_str(), false, &pattern_data); + if (success) { + std::string parsed_data = ctx.command.Construct(pattern_data); + success = + buildcc::env::save_file(output.string().c_str(), parsed_data, false); + } + + if (!success) { + buildcc::env::log_critical( + __FUNCTION__, fmt::format("Failed to parse {} -> {}", input, output)); + } + return success; +} + +} // namespace + +namespace buildcc { + +void TemplateGenerator::AddTemplate(const fs::path &input_filename, + const fs::path &output_filename) { + TemplateInfo info; + info.input = internal::Path::CreateNewPath( + command_.Construct(path_as_string(input_filename))) + .GetPathname(); + info.output = internal::Path::CreateNewPath( + command_.Construct(path_as_string(output_filename))) + .GetPathname(); + template_infos_.emplace_back(std::move(info)); +} + +std::string TemplateGenerator::Parse(const std::string &pattern) { + return command_.Construct(pattern); +} + +/** + * @brief Build FileGenerator Tasks + * + * Use `GetTaskflow` for the registered tasks + */ +void TemplateGenerator::Build() { + for (const auto &info : template_infos_) { + std::string name = + info.input.lexically_relative(Project::GetRootDir()).string(); + AddGenInfo(name, {info.input}, {info.output}, template_generate_cb); + } + this->CustomGenerator::Build(); +} + +} // namespace buildcc diff --git a/buildcc/lib/target/test/target/CMakeLists.txt b/buildcc/lib/target/test/target/CMakeLists.txt index a77da279..1e7ef314 100644 --- a/buildcc/lib/target/test/target/CMakeLists.txt +++ b/buildcc/lib/target/test/target/CMakeLists.txt @@ -47,15 +47,23 @@ add_executable(test_custom_generator ) target_link_libraries(test_custom_generator PRIVATE target_interface) -add_executable(test_generator - test_generator.cpp +add_executable(test_file_generator + test_file_generator.cpp ) -target_link_libraries(test_generator PRIVATE target_interface) +target_link_libraries(test_file_generator PRIVATE target_interface) + +add_executable(test_template_generator + test_template_generator.cpp +) +target_link_libraries(test_template_generator PRIVATE target_interface) add_test(NAME test_custom_generator COMMAND test_custom_generator WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) -add_test(NAME test_generator COMMAND test_generator +add_test(NAME test_file_generator COMMAND test_file_generator + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) +add_test(NAME test_template_generator COMMAND test_template_generator WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/buildcc/lib/target/test/target/data/template/default_values.txt.in b/buildcc/lib/target/test/target/data/template/default_values.txt.in new file mode 100644 index 00000000..9ea1d25f --- /dev/null +++ b/buildcc/lib/target/test/target/data/template/default_values.txt.in @@ -0,0 +1,4 @@ +{gen_root_dir} +{gen_build_dir} +{project_root_dir} +{project_build_dir} diff --git a/buildcc/lib/target/test/target/data/template/hello_world.txt.in b/buildcc/lib/target/test/target/data/template/hello_world.txt.in new file mode 100644 index 00000000..cd2ccb82 --- /dev/null +++ b/buildcc/lib/target/test/target/data/template/hello_world.txt.in @@ -0,0 +1 @@ +{hello} {world} diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp index a7c6ea71..5efa7e6f 100644 --- a/buildcc/lib/target/test/target/test_custom_generator.cpp +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -87,7 +87,7 @@ TEST(CustomGeneratorTestGroup, Basic_Failure) { TEST(CustomGeneratorTestGroup, DefaultArgumentUsage) { buildcc::CustomGenerator cgen("default_argument_usage", ""); - cgen.AddDefaultArguments({ + cgen.AddPatterns({ {"dummy_main_c", "{gen_root_dir}/dummy_main.c"}, {"dummy_main_o", "{gen_build_dir}/dummy_main.o"}, {"dummy_main_cpp", "{gen_root_dir}/dummy_main.cpp"}, diff --git a/buildcc/lib/target/test/target/test_generator.cpp b/buildcc/lib/target/test/target/test_file_generator.cpp similarity index 91% rename from buildcc/lib/target/test/target/test_generator.cpp rename to buildcc/lib/target/test/target/test_file_generator.cpp index 62c8b722..f6fc257e 100644 --- a/buildcc/lib/target/test/target/test_generator.cpp +++ b/buildcc/lib/target/test/target/test_file_generator.cpp @@ -1,4 +1,4 @@ -#include "target/generator.h" +#include "target/file_generator.h" #include "expect_command.h" #include "expect_custom_generator.h" @@ -16,7 +16,7 @@ #include "CppUTestExt/MockSupport.h" // clang-format off -TEST_GROUP(GeneratorTestGroup) +TEST_GROUP(FileGeneratorTestGroup) { void teardown() { buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); @@ -25,13 +25,13 @@ TEST_GROUP(GeneratorTestGroup) }; // clang-format on -fs::path BUILD_DIR = fs::current_path() / "intermediate" / "generator"; +fs::path BUILD_DIR = fs::current_path() / "intermediate" / "file_generator"; -TEST(GeneratorTestGroup, Generator_Build) { +TEST(FileGeneratorTestGroup, Generator_Build) { constexpr const char *const NAME = "Build"; buildcc::FileGenerator generator(NAME, ""); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"compiler", "gcc"}, }); @@ -47,11 +47,11 @@ TEST(GeneratorTestGroup, Generator_Build) { mock().checkExpectations(); } -TEST(GeneratorTestGroup, Generator_Identifier) { +TEST(FileGeneratorTestGroup, Generator_Identifier) { constexpr const char *const NAME = "Identifier"; buildcc::FileGenerator generator(NAME, ""); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"compiler", "gcc"}, }); @@ -66,7 +66,7 @@ TEST(GeneratorTestGroup, Generator_Identifier) { mock().checkExpectations(); } -TEST(GeneratorTestGroup, Generator_Rebuild) { +TEST(FileGeneratorTestGroup, Generator_Rebuild) { constexpr const char *const NAME = "Rebuild"; { buildcc::FileGenerator generator(NAME, ""); @@ -100,7 +100,7 @@ TEST(GeneratorTestGroup, Generator_Rebuild) { mock().checkExpectations(); } -TEST(GeneratorTestGroup, Generator_Rebuild_Inputs) { +TEST(FileGeneratorTestGroup, Generator_Rebuild_Inputs) { constexpr const char *const NAME = "Rebuild_Inputs"; { @@ -164,7 +164,7 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Inputs) { mock().checkExpectations(); } -TEST(GeneratorTestGroup, Generator_Rebuild_Outputs) { +TEST(FileGeneratorTestGroup, Generator_Rebuild_Outputs) { constexpr const char *const NAME = "Rebuild_Outputs"; { buildcc::FileGenerator generator(NAME, ""); @@ -213,7 +213,7 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Outputs) { mock().checkExpectations(); } -TEST(GeneratorTestGroup, Generator_Rebuild_Commands) { +TEST(FileGeneratorTestGroup, Generator_Rebuild_Commands) { constexpr const char *const NAME = "Rebuild_Commands"; { buildcc::FileGenerator generator(NAME, ""); @@ -259,27 +259,27 @@ TEST(GeneratorTestGroup, Generator_Rebuild_Commands) { mock().checkExpectations(); } -TEST(GeneratorTestGroup, Generator_AddDefaultArguments) { +TEST(FileGeneratorTestGroup, Generator_AddDefaultArguments) { constexpr const char *const NAME = "AddDefaultArgument"; buildcc::FileGenerator generator(NAME, ""); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"key", "value"}, }); - const std::string &value = generator.GetValueByIdentifier("key"); + const std::string &value = generator.Get("key"); STRCMP_EQUAL(value.c_str(), "value"); STRCMP_EQUAL(generator.GetName().c_str(), "AddDefaultArgument"); } // FAILURE STATES -TEST(GeneratorTestGroup, Generator_FailedEnvTaskState) { +TEST(FileGeneratorTestGroup, Generator_FailedEnvTaskState) { buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE); constexpr const char *const NAME = "FailedEnvTaskState"; buildcc::FileGenerator generator(NAME, ""); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"compiler", "gcc"}, }); @@ -296,11 +296,11 @@ TEST(GeneratorTestGroup, Generator_FailedEnvTaskState) { buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); } -TEST(GeneratorTestGroup, Generator_FailedGenerateConvert) { +TEST(FileGeneratorTestGroup, Generator_FailedGenerateConvert) { constexpr const char *const NAME = "FailedGenerateConvert"; buildcc::FileGenerator generator(NAME, ""); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"compiler", "gcc"}, }); @@ -319,11 +319,11 @@ TEST(GeneratorTestGroup, Generator_FailedGenerateConvert) { buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); } -TEST(GeneratorTestGroup, Generator_FailedGenerateCommand) { +TEST(FileGeneratorTestGroup, Generator_FailedGenerateCommand) { constexpr const char *const NAME = "FailedGenerateCommand"; buildcc::FileGenerator generator(NAME, ""); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"compiler", "gcc"}, }); @@ -341,14 +341,14 @@ TEST(GeneratorTestGroup, Generator_FailedGenerateCommand) { buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); } -TEST(GeneratorTestGroup, Generator_FailedStore) { +TEST(FileGeneratorTestGroup, Generator_FailedStore) { constexpr const char *const NAME = "FailedStore"; const fs::path test_build_dir = buildcc::Project::GetBuildDir() / NAME; buildcc::FileGenerator generator(NAME, ""); fs::remove_all(test_build_dir); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"compiler", "gcc"}, }); @@ -369,14 +369,14 @@ TEST(GeneratorTestGroup, Generator_FailedStore) { buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); } -TEST(GeneratorTestGroup, FailedEnvTaskState_Rebuild) { +TEST(FileGeneratorTestGroup, FailedEnvTaskState_Rebuild) { buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE); constexpr const char *const NAME = "FailedEnvTaskState_Rebuild"; { buildcc::FileGenerator generator(NAME, ""); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"compiler", "gcc"}, }); @@ -396,7 +396,7 @@ TEST(GeneratorTestGroup, FailedEnvTaskState_Rebuild) { { buildcc::FileGenerator generator(NAME, ""); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"compiler", "gcc"}, }); @@ -413,13 +413,13 @@ TEST(GeneratorTestGroup, FailedEnvTaskState_Rebuild) { mock().checkExpectations(); } -TEST(GeneratorTestGroup, FailedGenerateCommand_Rebuild) { +TEST(FileGeneratorTestGroup, FailedGenerateCommand_Rebuild) { constexpr const char *const NAME = "FailedGenerateCommand_Rebuild"; { buildcc::FileGenerator generator(NAME, ""); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"compiler", "gcc"}, }); @@ -440,7 +440,7 @@ TEST(GeneratorTestGroup, FailedGenerateCommand_Rebuild) { { buildcc::FileGenerator generator(NAME, ""); - generator.AddDefaultArguments({ + generator.AddPatterns({ {"compiler", "gcc"}, }); diff --git a/buildcc/lib/target/test/target/test_template_generator.cpp b/buildcc/lib/target/test/target/test_template_generator.cpp new file mode 100644 index 00000000..f84193fc --- /dev/null +++ b/buildcc/lib/target/test/target/test_template_generator.cpp @@ -0,0 +1,97 @@ +#include "target/template_generator.h" + +#include "expect_command.h" +#include "expect_custom_generator.h" +#include "test_target_util.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(TemplateGeneratorTestGroup) +{ + void teardown() { + mock().checkExpectations(); + mock().clear(); + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); + } +}; +// clang-format on + +fs::path BUILD_DIR = fs::current_path() / "intermediate" / "template_generator"; + +TEST(TemplateGeneratorTestGroup, Basic) { + buildcc::TemplateGenerator generator("basic", ""); + generator.Build(); + + buildcc::m::CustomGeneratorRunner(generator); +} + +TEST(TemplateGeneratorTestGroup, Basic_Parse) { + buildcc::TemplateGenerator generator("basic_parse", ""); + generator.AddPatterns({ + {"hello", "Hello"}, + {"world", "World"}, + }); + std::string parsed = generator.Parse("{hello} {world}"); + STRCMP_EQUAL(parsed.c_str(), "Hello World"); +} + +TEST(TemplateGeneratorTestGroup, Basic_InputParse) { + buildcc::TemplateGenerator generator("basic_inputparse", ""); + generator.AddPatterns({ + {"hello", "Hello"}, + {"world", "World"}, + }); + generator.AddTemplate("{gen_root_dir}/template/default_values.txt.in", + "{gen_build_dir}/default_values.txt"); + generator.AddTemplate("{gen_root_dir}/template/hello_world.txt.in", + "{gen_build_dir}/hello_world.txt"); + generator.Build(); + + buildcc::m::CustomGeneratorRunner(generator); + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); +} + +TEST(TemplateGeneratorTestGroup, Basic_SaveFailure) { + constexpr const char *const NAME = "basic_save_failure"; + { + buildcc::TemplateGenerator generator(NAME, ""); + + fs::create_directories(generator.GetBuildDir() / "default_values.txt"); + + generator.AddTemplate("{gen_root_dir}/template/default_values.txt.in", + "{gen_build_dir}/default_values.txt"); + generator.Build(); + + buildcc::m::CustomGeneratorRunner(generator); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); + } +} + +TEST(TemplateGeneratorTestGroup, Basic_LoadFailure) { + constexpr const char *const NAME = "basic_load_failure"; + { + buildcc::TemplateGenerator generator(NAME, ""); + + fs::create_directories(generator.GetBuildDir() / "default_values.txt.in"); + + generator.AddTemplate("{gen_build_dir}/default_values.txt.in", + "{gen_build_dir}/default_values.txt"); + generator.Build(); + + buildcc::m::CustomGeneratorRunner(generator); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); + } +} + +int main(int ac, char **av) { + fs::remove_all(BUILD_DIR); + buildcc::Project::Init(fs::current_path() / "data", BUILD_DIR); + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/schema/include/schema/target_serialization.h b/buildcc/schema/include/schema/target_serialization.h index 84914ffb..e4869f3b 100644 --- a/buildcc/schema/include/schema/target_serialization.h +++ b/buildcc/schema/include/schema/target_serialization.h @@ -28,7 +28,7 @@ namespace buildcc::internal { struct TargetSchema { std::string name; - TargetType type; + TargetType type{TargetType::Undefined}; path_unordered_set internal_sources; path_unordered_set internal_headers; diff --git a/buildcc/schema/include/schema/target_type.h b/buildcc/schema/include/schema/target_type.h index eb4632ab..866b030b 100644 --- a/buildcc/schema/include/schema/target_type.h +++ b/buildcc/schema/include/schema/target_type.h @@ -23,6 +23,7 @@ enum class TargetType { Executable, ///< Executable Target type StaticLibrary, ///< Static library target type DynamicLibrary, ///< Dynamic library target type + Undefined, ///< Undefined target type }; } diff --git a/example/hybrid/dep_chaining/build.cpp b/example/hybrid/dep_chaining/build.cpp index 906ecfe6..33f5bcff 100644 --- a/example/hybrid/dep_chaining/build.cpp +++ b/example/hybrid/dep_chaining/build.cpp @@ -83,15 +83,14 @@ static void clean_cb() { static void cpp_target_cb(BaseTarget &cpptarget, const FileGenerator &cpp_generator) { - const fs::path main_cpp = - fs::path(cpp_generator.GetValueByIdentifier("main_cpp")) - .lexically_relative(Project::GetRootDir()); + const fs::path main_cpp = fs::path(cpp_generator.Get("main_cpp")) + .lexically_relative(Project::GetRootDir()); cpptarget.AddSource(main_cpp); cpptarget.Build(); } static void c_target_cb(BaseTarget &ctarget, const FileGenerator &c_generator) { - const fs::path main_c = fs::path(c_generator.GetValueByIdentifier("main_c")) + const fs::path main_c = fs::path(c_generator.Get("main_c")) .lexically_relative(Project::GetRootDir()); ctarget.AddSource(main_c); ctarget.Build(); From 8b00500dd13f66a678448153adf0943be65173cd Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 17 May 2022 21:08:05 -0700 Subject: [PATCH 22/35] Custom generator groups (#215) - Group subflows into a subflow group - This can then be used by Target to create easy task dependencies --- .../target/include/target/custom_generator.h | 72 +++-- .../target/include/target/file_generator.h | 6 +- .../include/target/template_generator.h | 8 +- .../src/custom_generator/custom_generator.cpp | 185 ++++++++----- .../target/src/generator/file_generator.cpp | 64 ++--- .../src/generator/template_generator.cpp | 8 +- .../test/target/test_custom_generator.cpp | 248 +++++++++++++++++- 7 files changed, 459 insertions(+), 132 deletions(-) diff --git a/buildcc/lib/target/include/target/custom_generator.h b/buildcc/lib/target/include/target/custom_generator.h index 76e64576..316290ea 100644 --- a/buildcc/lib/target/include/target/custom_generator.h +++ b/buildcc/lib/target/include/target/custom_generator.h @@ -41,23 +41,27 @@ namespace buildcc { class CustomGeneratorContext { public: CustomGeneratorContext(const env::Command &c, const fs_unordered_set &i, - const fs_unordered_set &o) - : command(c), inputs(i), outputs(o) {} + const fs_unordered_set &o, + const std::vector &ub) + : command(c), inputs(i), outputs(o), userblob(ub) {} -public: const env::Command &command; const fs_unordered_set &inputs; const fs_unordered_set &outputs; + const std::vector &userblob; }; // clang-format off -typedef std::function GenerateCb; +using GenerateCb = std::function; -typedef std::function &)> DependencyCb; +using DependencyCb = std::function &&)>; // clang-format on class CustomBlobHandler { public: + CustomBlobHandler() = default; + virtual ~CustomBlobHandler() = default; + bool CheckChanged(const std::vector &previous, const std::vector ¤t) const { env::assert_fatal( @@ -69,7 +73,7 @@ class CustomBlobHandler { return !IsEqual(previous, current); }; - std::vector GetSerializedData() { + std::vector GetSerializedData() const { auto serialized_data = Serialize(); env::assert_fatal( Verify(serialized_data), @@ -94,12 +98,11 @@ struct UserCustomGeneratorSchema : public internal::CustomGeneratorSchema { std::unordered_map gen_info_map; void ConvertToInternal() { - for (auto &r_miter : gen_info_map) { - r_miter.second.internal_inputs = path_schema_convert( - r_miter.second.inputs, internal::Path::CreateExistingPath); - auto p = internal_gen_info_map.emplace(r_miter.first, r_miter.second); - env::assert_fatal(p.second, - fmt::format("Could not save {}", r_miter.first)); + for (auto &[id, gen_info] : gen_info_map) { + gen_info.internal_inputs = path_schema_convert( + gen_info.inputs, internal::Path::CreateExistingPath); + auto [_, success] = internal_gen_info_map.try_emplace(id, gen_info); + env::assert_fatal(success, fmt::format("Could not save {}", id)); } } }; @@ -136,6 +139,10 @@ class CustomGenerator : public internal::BuilderInterface { const GenerateCb &generate_cb, std::shared_ptr blob_handler = nullptr); + void AddGroup(const std::string &group_id, + std::initializer_list ids, + const DependencyCb &dependency_cb = DependencyCb()); + // Callbacks /** * @brief Setup dependencies between Tasks using their `id` @@ -168,12 +175,16 @@ class CustomGenerator : public internal::BuilderInterface { private: void Initialize(); - template void TaskRunner(const std::string &id); + void TaskRunner(bool run, const std::string &id); + tf::Task CreateTaskRunner(tf::Subflow &subflow, bool build, + const std::string &id); void GenerateTask(); - void BuildGenerate( - std::unordered_map &gen_selected_map, - std::unordered_map &dummy_gen_selected_map); + void BuildGenerate(std::unordered_set &gen_selected_ids, + std::unordered_set &dummy_gen_selected_ids); + + void InvokeDependencyCb(std::unordered_map + &®istered_tasks) const noexcept; // Recheck states void IdRemoved(); @@ -181,7 +192,31 @@ class CustomGenerator : public internal::BuilderInterface { void IdUpdated(); protected: - env::Command command_; + const env::Command &ConstCommand() const { return command_; } + env::Command &RefCommand() { return command_; } + +private: + struct GroupMetadata { + std::vector ids; + DependencyCb dependency_cb; + + void InvokeDependencyCb(const std::string &group_id, + std::unordered_map + &®istered_tasks) const noexcept { + if (!dependency_cb) { + return; + } + try { + dependency_cb(std::move(registered_tasks)); + } catch (...) { + env::log_critical( + __FUNCTION__, + fmt::format("Dependency callback failed for group id {}", + group_id)); + env::set_task_state(env::TaskState::FAILURE); + } + } + }; private: std::string name_; @@ -190,11 +225,14 @@ class CustomGenerator : public internal::BuilderInterface { // Serialization UserCustomGeneratorSchema user_; + std::unordered_map grouped_ids_; + std::unordered_set ungrouped_ids_; std::mutex success_schema_mutex_; std::unordered_map success_schema_; // Internal + env::Command command_; tf::Taskflow tf_; // Callbacks diff --git a/buildcc/lib/target/include/target/file_generator.h b/buildcc/lib/target/include/target/file_generator.h index 08eb1d99..cc4b66b0 100644 --- a/buildcc/lib/target/include/target/file_generator.h +++ b/buildcc/lib/target/include/target/file_generator.h @@ -23,9 +23,8 @@ namespace buildcc { class FileGenerator : public CustomGenerator { public: - FileGenerator(const std::string &name, const TargetEnv &env) - : CustomGenerator(name, env) {} - virtual ~FileGenerator() = default; + using CustomGenerator::CustomGenerator; + ~FileGenerator() override = default; FileGenerator(const FileGenerator &) = delete; /** @@ -73,6 +72,7 @@ class FileGenerator : public CustomGenerator { private: using CustomGenerator::AddDependencyCb; using CustomGenerator::AddGenInfo; + using CustomGenerator::AddGroup; using CustomGenerator::Build; private: diff --git a/buildcc/lib/target/include/target/template_generator.h b/buildcc/lib/target/include/target/template_generator.h index 2d2061a5..b22d49c0 100644 --- a/buildcc/lib/target/include/target/template_generator.h +++ b/buildcc/lib/target/include/target/template_generator.h @@ -23,12 +23,13 @@ namespace buildcc { class TemplateGenerator : public CustomGenerator { public: - TemplateGenerator(const std::string &name, const TargetEnv &env) - : CustomGenerator(name, env) {} + using CustomGenerator::CustomGenerator; + ~TemplateGenerator() override = default; + TemplateGenerator(const TemplateGenerator &) = delete; void AddTemplate(const fs::path &input_filename, const fs::path &output_filename); - std::string Parse(const std::string &pattern); + std::string Parse(const std::string &pattern) const; /** * @brief Build FileGenerator Tasks @@ -41,6 +42,7 @@ class TemplateGenerator : public CustomGenerator { private: using CustomGenerator::AddDependencyCb; using CustomGenerator::AddGenInfo; + using CustomGenerator::AddGroup; using CustomGenerator::Build; private: diff --git a/buildcc/lib/target/src/custom_generator/custom_generator.cpp b/buildcc/lib/target/src/custom_generator/custom_generator.cpp index 466d43dd..c488a54b 100644 --- a/buildcc/lib/target/src/custom_generator/custom_generator.cpp +++ b/buildcc/lib/target/src/custom_generator/custom_generator.cpp @@ -17,10 +17,7 @@ #include "target/custom_generator.h" namespace { -constexpr const char *const kStartGeneratorTaskName = "Start Generator"; -constexpr const char *const kEndGeneratorTaskName = "End Generator"; -constexpr const char *const kCommandTaskName = "Command"; constexpr const char *const kGenerateTaskName = "Generate"; } // namespace @@ -34,8 +31,8 @@ void CustomGenerator::AddPattern(const std::string &identifier, void CustomGenerator::AddPatterns( const std::unordered_map &pattern_map) { - for (const auto &arg_iter : pattern_map) { - AddPattern(arg_iter.first, arg_iter.second); + for (const auto &[identifier, pattern] : pattern_map) { + AddPattern(identifier, pattern); } } @@ -67,7 +64,29 @@ void CustomGenerator::AddGenInfo( } schema.generate_cb = generate_cb; schema.blob_handler = std::move(blob_handler); - user_.gen_info_map.emplace(id, std::move(schema)); + user_.gen_info_map.try_emplace(id, std::move(schema)); + ungrouped_ids_.emplace(id); +} + +void CustomGenerator::AddGroup(const std::string &group_id, + std::initializer_list ids, + const DependencyCb &dependency_cb) { + // Verify that the ids exist + // Remove those ids from ungrouped_ids + for (const auto &id : ids) { + env::assert_fatal(user_.gen_info_map.find(id) != user_.gen_info_map.end(), + fmt::format("Id '{}' is not found", id)); + ungrouped_ids_.erase(id); + } + + env::assert_fatal(grouped_ids_.find(group_id) == grouped_ids_.end(), + fmt::format("Group Id '{}' duplicate found", group_id)); + + // Group map is used to group similar ids in a single subflow + GroupMetadata group_metadata; + group_metadata.ids = ids; + group_metadata.dependency_cb = dependency_cb; + grouped_ids_.try_emplace(group_id, std::move(group_metadata)); } void CustomGenerator::AddDependencyCb(const DependencyCb &dependency_cb) { @@ -102,10 +121,12 @@ void CustomGenerator::Initialize() { } void CustomGenerator::BuildGenerate( - std::unordered_map &gen_selected_map, - std::unordered_map &dummy_gen_selected_map) { + std::unordered_set &gen_selected_ids, + std::unordered_set &dummy_gen_selected_ids) { if (!serialization_.IsLoaded()) { - gen_selected_map = user_.gen_info_map; + std::for_each( + user_.gen_info_map.begin(), user_.gen_info_map.end(), + [&](const auto &iter) { gen_selected_ids.insert(iter.first); }); dirty_ = true; } else { // DONE, Conditionally select internal_gen_info_map depending on what has @@ -118,8 +139,7 @@ void CustomGenerator::BuildGenerate( // curr_gen_info_map If prev_gen_info_map does not exist in // curr_gen_info_map, has been removed from existing build We need this // condition to only set the dirty_ flag - for (const auto &prev_miter : prev_gen_info_map) { - const auto &id = prev_miter.first; + for (const auto &[id, _] : prev_gen_info_map) { if (curr_gen_info_map.find(id) == curr_gen_info_map.end()) { // MAP REMOVED condition IdRemoved(); @@ -131,18 +151,17 @@ void CustomGenerator::BuildGenerate( // DONE, MAP ADDED condition Check if curr_gen_info_map exists in // prev_gen_info_map If curr_gen_info_map does not exist in // prev_gen_info_map, has been added to existing build - for (const auto &curr_miter : curr_gen_info_map) { - const auto &id = curr_miter.first; + for (const auto &[id, _] : curr_gen_info_map) { if (prev_gen_info_map.find(id) == prev_gen_info_map.end()) { // MAP ADDED condition IdAdded(); - gen_selected_map.emplace(curr_miter.first, curr_miter.second); + gen_selected_ids.insert(id); dirty_ = true; } else { // MAP UPDATED condition (*checked later) // This is because tasks can have dependencies amongst each other we can // compute task level rebuilds later - dummy_gen_selected_map.emplace(curr_miter.first, curr_miter.second); + dummy_gen_selected_ids.insert(id); } } } @@ -155,51 +174,51 @@ void CustomGenerator::GenerateTask() { } try { - std::unordered_map selected_user_schema; - std::unordered_map dummy_selected_user_schema; - BuildGenerate(selected_user_schema, dummy_selected_user_schema); - - std::unordered_map task_map; - // Create task for selected schema - for (const auto &selected_miter : selected_user_schema) { - const auto &id = selected_miter.first; - // const auto ¤t_info = selected_miter.second; - tf::Task task = subflow - .emplace([&]() { - try { - TaskRunner(id); - } catch (...) { - env::set_task_state(env::TaskState::FAILURE); - } - }) - .name(id); - task_map.emplace(id, task); + std::unordered_map registered_tasks; + + // Selected ids for build + std::unordered_set selected_ids; + std::unordered_set dummy_selected_ids; + BuildGenerate(selected_ids, dummy_selected_ids); + + // Grouped tasks + for (const auto &[first, second] : grouped_ids_) { + const auto &group_id = first; + const auto &group_metadata = second; + auto group_task = subflow.emplace([&](tf::Subflow &s) { + std::unordered_map reg_tasks; + + if (env::get_task_state() != env::TaskState::SUCCESS) { + return; + } + + for (const auto &id : group_metadata.ids) { + bool build = selected_ids.count(id) == 1; + auto task = CreateTaskRunner(s, build, id); + task.name(id); + reg_tasks.try_emplace(id, task); + } + + // Dependency callback + group_metadata.InvokeDependencyCb(group_id, std::move(reg_tasks)); + + // NOTE, Do not call detach otherwise this will fail + s.join(); + }); + group_task.name(group_id); + registered_tasks.try_emplace(group_id, group_task); } - for (auto &dummy_selected_miter : dummy_selected_user_schema) { - const auto &id = dummy_selected_miter.first; - // const auto ¤t_info = dummy_selected_miter.second; - tf::Task task = subflow - .emplace([&]() { - try { - TaskRunner(id); - } catch (...) { - env::set_task_state(env::TaskState::FAILURE); - } - }) - .name(id); - task_map.emplace(id, task); + // Ungrouped tasks + for (const auto &id : ungrouped_ids_) { + bool build = selected_ids.count(id) == 1; + auto task = CreateTaskRunner(subflow, build, id); + task.name(id); + registered_tasks.try_emplace(id, task); } - // Dependencies between ids - if (dependency_cb_) { - try { - dependency_cb_(task_map); - } catch (...) { - env::log_critical(__FUNCTION__, "Dependency callback failed"); - env::set_task_state(env::TaskState::FAILURE); - } - } + // Dependencies between tasks + InvokeDependencyCb(std::move(registered_tasks)); // NOTE, Do not call detach otherwise this will fail subflow.join(); @@ -224,22 +243,47 @@ void CustomGenerator::GenerateTask() { generate_task.name(kGenerateTaskName); } -template void CustomGenerator::TaskRunner(const std::string &id) { - // Convert - { - auto ¤t_gen_info = user_.gen_info_map.at(id); - current_gen_info.internal_inputs = internal::path_schema_convert( - current_gen_info.inputs, internal::Path::CreateExistingPath); - current_gen_info.userblob = - current_gen_info.blob_handler != nullptr - ? current_gen_info.blob_handler->GetSerializedData() - : std::vector(); +void CustomGenerator::InvokeDependencyCb( + std::unordered_map &®istered_tasks) + const noexcept { + if (dependency_cb_) { + try { + dependency_cb_(std::move(registered_tasks)); + } catch (...) { + env::log_critical(__FUNCTION__, "Dependency callback failed"); + env::set_task_state(env::TaskState::FAILURE); + } } +} + +tf::Task CustomGenerator::CreateTaskRunner(tf::Subflow &subflow, bool build, + const std::string &id) { + return subflow.emplace([&, build, id]() { + if (env::get_task_state() != env::TaskState::SUCCESS) { + return; + } + try { + TaskRunner(build, id); + } catch (...) { + env::set_task_state(env::TaskState::FAILURE); + } + }); +} + +void CustomGenerator::TaskRunner(bool run, const std::string &id) { + // Convert + auto ¤t_gen_info = user_.gen_info_map.at(id); + current_gen_info.internal_inputs = internal::path_schema_convert( + current_gen_info.inputs, internal::Path::CreateExistingPath); + current_gen_info.userblob = + current_gen_info.blob_handler != nullptr + ? current_gen_info.blob_handler->GetSerializedData() + : std::vector(); // Run const auto ¤t_info = user_.gen_info_map.at(id); bool rerun = false; - if constexpr (run) { + if (run) { rerun = true; } else { const auto &previous_info = @@ -257,13 +301,14 @@ template void CustomGenerator::TaskRunner(const std::string &id) { if (rerun) { dirty_ = true; buildcc::CustomGeneratorContext ctx(command_, current_info.inputs, - current_info.outputs); + current_info.outputs, + current_info.userblob); bool success = current_info.generate_cb(ctx); env::assert_fatal(success, fmt::format("Generate Cb failed for id {}", id)); } - std::lock_guard guard(success_schema_mutex_); - success_schema_.emplace(id, current_info); + std::scoped_lock guard(success_schema_mutex_); + success_schema_.try_emplace(id, current_info); } } // namespace buildcc diff --git a/buildcc/lib/target/src/generator/file_generator.cpp b/buildcc/lib/target/src/generator/file_generator.cpp index ca94d9e2..1362ed32 100644 --- a/buildcc/lib/target/src/generator/file_generator.cpp +++ b/buildcc/lib/target/src/generator/file_generator.cpp @@ -24,11 +24,22 @@ namespace { -class GeneratorBlobHandler : public buildcc::CustomBlobHandler { +class FileGeneratorBlobHandler : public buildcc::CustomBlobHandler { public: - explicit GeneratorBlobHandler(const std::vector &commands) + explicit FileGeneratorBlobHandler(const std::vector &commands) : commands_(commands) {} + // serialized_data has already been verified + static std::vector + Deserialize(const std::vector &serialized_data) { + std::vector deserialized; + auto flex_vect = flexbuffers::GetRoot(serialized_data).AsVector(); + for (size_t i = 0; i < flex_vect.size(); i++) { + deserialized.emplace_back(flex_vect[i].AsString().str()); + } + return deserialized; + } + private: const std::vector &commands_; @@ -61,18 +72,24 @@ class GeneratorBlobHandler : public buildcc::CustomBlobHandler { builder.Finish(); return builder.GetBuffer(); } +}; - // serialized_data has already been verified - static std::vector - Deserialize(const std::vector &serialized_data) { - std::vector deserialized; - auto flex_vect = flexbuffers::GetRoot(serialized_data).AsVector(); - for (size_t i = 0; i < flex_vect.size(); i++) { - deserialized.emplace_back(flex_vect[i].AsString().str()); +bool FileGeneratorGenerateCb(const buildcc::CustomGeneratorContext &ctx) { + (void)ctx; + bool success = true; + std::vector commands = + FileGeneratorBlobHandler::Deserialize(ctx.userblob); + for (const auto &c : commands) { + bool executed = buildcc::env::Command::Execute(c); + if (!executed) { + success = false; + buildcc::env::log_critical(__FUNCTION__, + fmt::format("Failed to run command {}", c)); + break; } - return deserialized; } -}; + return success; +} } // namespace @@ -81,7 +98,7 @@ namespace buildcc { void FileGenerator::AddInput(const std::string &absolute_input_pattern, const char *identifier) { std::string absolute_input_string = - command_.Construct(absolute_input_pattern); + RefCommand().Construct(absolute_input_pattern); const auto absolute_input_path = internal::Path::CreateNewPath(absolute_input_string); inputs_.insert(absolute_input_path.GetPathname()); @@ -94,7 +111,7 @@ void FileGenerator::AddInput(const std::string &absolute_input_pattern, void FileGenerator::AddOutput(const std::string &absolute_output_pattern, const char *identifier) { std::string absolute_output_string = - command_.Construct(absolute_output_pattern); + RefCommand().Construct(absolute_output_pattern); const auto absolute_output_path = internal::Path::CreateNewPath(absolute_output_string); outputs_.insert(absolute_output_path.GetPathname()); @@ -108,28 +125,13 @@ void FileGenerator::AddCommand( const std::string &command_pattern, const std::unordered_map &arguments) { std::string constructed_command = - command_.Construct(command_pattern, arguments); + RefCommand().Construct(command_pattern, arguments); commands_.emplace_back(std::move(constructed_command)); } void FileGenerator::Build() { - AddGenInfo( - "Generate", inputs_, outputs_, - [&](const CustomGeneratorContext &ctx) -> bool { - (void)ctx; - bool success = true; - for (const auto &c : commands_) { - bool executed = env::Command::Execute(c); - if (!executed) { - success = false; - env::log_critical(__FUNCTION__, - fmt::format("Failed to run command {}", c)); - break; - } - } - return success; - }, - std::make_shared(commands_)); + AddGenInfo("Generate", inputs_, outputs_, FileGeneratorGenerateCb, + std::make_shared(commands_)); this->CustomGenerator::Build(); } diff --git a/buildcc/lib/target/src/generator/template_generator.cpp b/buildcc/lib/target/src/generator/template_generator.cpp index c99fc541..e7c059c0 100644 --- a/buildcc/lib/target/src/generator/template_generator.cpp +++ b/buildcc/lib/target/src/generator/template_generator.cpp @@ -48,16 +48,16 @@ void TemplateGenerator::AddTemplate(const fs::path &input_filename, const fs::path &output_filename) { TemplateInfo info; info.input = internal::Path::CreateNewPath( - command_.Construct(path_as_string(input_filename))) + RefCommand().Construct(path_as_string(input_filename))) .GetPathname(); info.output = internal::Path::CreateNewPath( - command_.Construct(path_as_string(output_filename))) + RefCommand().Construct(path_as_string(output_filename))) .GetPathname(); template_infos_.emplace_back(std::move(info)); } -std::string TemplateGenerator::Parse(const std::string &pattern) { - return command_.Construct(pattern); +std::string TemplateGenerator::Parse(const std::string &pattern) const { + return ConstCommand().Construct(pattern); } /** diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp index 5efa7e6f..ea3eef74 100644 --- a/buildcc/lib/target/test/target/test_custom_generator.cpp +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -85,6 +85,235 @@ TEST(CustomGeneratorTestGroup, Basic_Failure) { CHECK_EQUAL(internal_map.size(), 1); } +TEST(CustomGeneratorTestGroup, Basic_Group) { + buildcc::CustomGenerator cgen("basic_group", ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.AddGroup("grouped_id1_and_id2", {"id1", "id2"}); + cgen.Build(); + + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + buildcc::m::CustomGeneratorRunner(cgen); + + // Serialization check + { + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + + const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(internal_map.size(), 2); + const auto &id1_info = internal_map.at("id1"); + CHECK_EQUAL(id1_info.internal_inputs.size(), 1); + CHECK_EQUAL(id1_info.outputs.size(), 1); + + const auto &id2_info = internal_map.at("id2"); + CHECK_EQUAL(id2_info.internal_inputs.size(), 1); + CHECK_EQUAL(id2_info.outputs.size(), 0); + } +} + +TEST(CustomGeneratorTestGroup, Basic_Group_Dependency) { + buildcc::CustomGenerator cgen("basic_group_dependency", ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.AddGroup("grouped_id1_and_id2", {"id1", "id2"}, [](auto &&task_map) { + task_map.at("id1").precede(task_map.at("id2")); + }); + cgen.Build(); + + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + buildcc::m::CustomGeneratorRunner(cgen); + + // Serialization check + { + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + + const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(internal_map.size(), 2); + const auto &id1_info = internal_map.at("id1"); + CHECK_EQUAL(id1_info.internal_inputs.size(), 1); + CHECK_EQUAL(id1_info.outputs.size(), 1); + + const auto &id2_info = internal_map.at("id2"); + CHECK_EQUAL(id2_info.internal_inputs.size(), 1); + CHECK_EQUAL(id2_info.outputs.size(), 0); + } +} + +TEST(CustomGeneratorTestGroup, Basic_Group_DependencyFailure) { + buildcc::CustomGenerator cgen("basic_group_dependency_failure", ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.AddGroup("grouped_id1_and_id2", {"id1", "id2"}, [](auto &&task_map) { + task_map.at("id1").precede(task_map.at("id2")); + buildcc::env::assert_fatal("Failure"); + }); + cgen.Build(); + + buildcc::m::CustomGeneratorRunner(cgen); + + // Serialization check + { + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + + const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(internal_map.size(), 0); + } + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); +} + +bool FailureCb(const buildcc::CustomGeneratorContext &ctx) { + (void)ctx; + return false; +} +bool SuccessCb(const buildcc::CustomGeneratorContext &ctx) { + (void)ctx; + return true; +} + +// An ungrouped task a dependency on a grouped task and fail the +// ungrouped task +TEST(CustomGeneratorTestGroup, Basic_Group_DependencyFailure2) { + buildcc::CustomGenerator cgen("basic_group_dependency_failure2", ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, FailureCb); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, SuccessCb); + cgen.AddGroup("grouped_id2", {"id2"}); + cgen.AddDependencyCb([&](auto &&task_map) { + task_map.at("id1").precede(task_map.at("grouped_id2")); + }); + cgen.Build(); + + buildcc::m::CustomGeneratorRunner(cgen); + + // Serialization check + { + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + + const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(internal_map.size(), 0); + } + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); +} + +// Behaviour +// Initial: A | B -> Passes +// Changes: (GID:NEW)[A -> B] -> No rebuild triggered + +// Behaviour +// Initial: A | B -> Fails +// Changes: (GID:NEW)[A -> B] -> rebuild triggered due to previous failure + +// ! IMPORTANT +// * NOTE, It is users responsibility to make sure that when A -> B, A's data +// change should automatically trigger B + +// For example: Say A -> B i.e B depends on A +// In a typical scenario, B would depend on A's output +// To make sure B is triggered when A changes. Make sure you use A's output in +// B's userblob. +// In this way whenever A changes, B's userblob automatically becomes "newer" +// and triggers a rebuild as well + +// Say, A gives out "rebuild = true/false" as its output +// We can use this "rebuild" variable in B's userblob +// When A runs and "rebuild" changes from false to true, During the `TaskRunner` +// we check B's userblob and automatically invoke the `CheckChanged` virtual +// call +// TODO, Create a testcase for the above scenario (Advanced_DependencyRebuild +// scenario) + +// DONE, Make B fail because it properly depends on A +static bool rebuild_value{false}; +static bool ProperDependency1(const buildcc::CustomGeneratorContext &ctx) { + (void)ctx; + mock().actualCall("ProperDependency1"); + rebuild_value = true; + return true; +} + +static bool ProperDependency2(const buildcc::CustomGeneratorContext &ctx) { + (void)ctx; + mock().actualCall("ProperDependency2"); + return rebuild_value; +} + +// ProperDependency2 depends on ProperDependency1 completion +TEST(CustomGeneratorTestGroup, Basic_ProperDependency_GoodCase) { + rebuild_value = false; + + buildcc::CustomGenerator cgen("basic_proper_dependency_good_case", ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, ProperDependency1); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + ProperDependency2); + cgen.AddDependencyCb( + [](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); + cgen.Build(); + + mock().expectOneCall("ProperDependency1"); + mock().expectOneCall("ProperDependency2"); + buildcc::m::CustomGeneratorRunner(cgen); + + // Serialization check + { + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + + const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(internal_map.size(), 2); + } + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); +} + +// ProperDependency2 depends on ProperDependency1 completion +TEST(CustomGeneratorTestGroup, Basic_ProperDependency_BadCase) { + rebuild_value = false; + + buildcc::CustomGenerator cgen("basic_proper_dependency_bad_case", ""); + cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, + {"{gen_build_dir}/dummy_main.o"}, ProperDependency1); + cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + ProperDependency2); + cgen.AddDependencyCb( + [](auto &&task_map) { task_map.at("id2").precede(task_map.at("id1")); }); + cgen.Build(); + + mock().expectOneCall("ProperDependency2"); + buildcc::m::CustomGeneratorRunner(cgen); + + // Serialization check + { + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); + + const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(internal_map.size(), 0); + } + + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); +} + TEST(CustomGeneratorTestGroup, DefaultArgumentUsage) { buildcc::CustomGenerator cgen("default_argument_usage", ""); cgen.AddPatterns({ @@ -183,7 +412,7 @@ static bool Dep2Cb(const buildcc::CustomGeneratorContext &ctx) { return buildcc::env::Command::Execute(""); } -static void DependencyCb(std::unordered_map &task_map) { +static void DependencyCb(std::unordered_map &&task_map) { task_map.at("id1").precede(task_map.at("id2")); } @@ -417,8 +646,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { mock().expectOneCall("RealGenerateCb"); buildcc::env::m::CommandExpect_Execute(1, false); - mock().expectOneCall("RealGenerateCb"); - buildcc::env::m::CommandExpect_Execute(1, true); + + // Since there is an error above, second command does not execute (note, + // this is the behaviour in a single thread that is why we can + // check sequentially) buildcc::m::CustomGeneratorRunner(cgen); CHECK_TRUE(buildcc::env::get_task_state() == @@ -427,7 +658,7 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 0); fs::remove_all(cgen.GetBinaryPath()); } @@ -515,6 +746,9 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddDependencyCb([](auto &&task_map) { + task_map.at("id1").precede(task_map.at("id2")); + }); cgen.Build(); buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); @@ -576,6 +810,9 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, {"{gen_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.AddDependencyCb([](auto &&task_map) { + task_map.at("id1").precede(task_map.at("id2")); + }); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -609,6 +846,9 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, {"{gen_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.AddDependencyCb([](auto &&task_map) { + task_map.at("id1").precede(task_map.at("id2")); + }); cgen.Build(); mock().expectOneCall("RealGenerateCb"); From 05ad3df6c57785e7eb9470fef7d141fcf4bd69fd Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 15 Oct 2022 01:11:33 -0700 Subject: [PATCH 23/35] Generator code refactoring (#216) --- bootstrap/src/build_buildcc.cpp | 26 ++- .../lib/target/cmake/common_target_src.cmake | 1 + buildcc/lib/target/cmake/mock_target.cmake | 1 - buildcc/lib/target/cmake/target.cmake | 1 - .../target/include/target/custom_generator.h | 10 +- .../target/include/target/file_generator.h | 14 +- buildcc/lib/target/include/target/target.h | 14 +- .../include/target/template_generator.h | 10 +- .../src/custom_generator/custom_generator.cpp | 25 +-- .../target/src/generator/file_generator.cpp | 29 +-- .../src/generator/template_generator.cpp | 22 +- buildcc/lib/target/src/target/build.cpp | 7 +- buildcc/lib/target/src/target/tasks.cpp | 72 ++----- .../data/template/default_values.txt.in | 4 +- .../test/target/test_custom_generator.cpp | 197 +++++++++--------- .../test/target/test_file_generator.cpp | 168 +++++++-------- .../target/test_target_failure_states.cpp | 28 +-- .../target/test/target/test_target_pch.cpp | 23 ++ .../target/test/target/test_target_source.cpp | 2 +- .../test/target/test_template_generator.cpp | 16 +- buildcc/schema/include/schema/path.h | 24 ++- example/hybrid/dep_chaining/build.cpp | 16 +- 22 files changed, 347 insertions(+), 363 deletions(-) diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index 8669dffc..8a0806fe 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -19,22 +19,26 @@ namespace buildcc { void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe) { - generator.AddInput("{gen_root_dir}/path.fbs", "path_fbs"); - generator.AddInput("{gen_root_dir}/custom_generator.fbs", - "custom_generator_fbs"); - generator.AddInput("{gen_root_dir}/target.fbs", "target_fbs"); + generator.AddPattern("path_fbs", "{current_root_dir}/path.fbs"); + generator.AddPattern("custom_generator_fbs", + "{current_root_dir}/custom_generator.fbs"); + generator.AddPattern("target_fbs", "{current_root_dir}/target.fbs"); - generator.AddOutput("{gen_build_dir}/path_generated.h"); - generator.AddOutput("{gen_build_dir}/custom_generator_generated.h"); - generator.AddOutput("{gen_build_dir}/target_generated.h"); + generator.AddInput("{path_fbs}"); + generator.AddInput("{custom_generator_fbs}"); + generator.AddInput("{target_fbs}"); + + generator.AddOutput("{current_build_dir}/path_generated.h"); + generator.AddOutput("{current_build_dir}/custom_generator_generated.h"); + generator.AddOutput("{current_build_dir}/target_generated.h"); generator.AddPatterns({ {"flatc_compiler", fmt::format("{}", flatc_exe.GetTargetPath())}, }); // generator.AddCommand("{flatc_compiler} --help"); - generator.AddCommand( - "{flatc_compiler} -o {gen_build_dir} -I {gen_root_dir} --gen-object-api " - "--cpp {path_fbs} {custom_generator_fbs} {target_fbs}"); + generator.AddCommand("{flatc_compiler} -o {current_build_dir} -I " + "{current_root_dir} --gen-object-api " + "--cpp {path_fbs} {custom_generator_fbs} {target_fbs}"); generator.Build(); } @@ -45,7 +49,7 @@ void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, const TargetInfo &taskflow_ho, const BaseTarget &tpl) { // NOTE, Build as single lib target.AddIncludeDir("", true); - const std::string &schema_build_dir = schema_gen.Get("gen_build_dir"); + const std::string &schema_build_dir = schema_gen.Get("current_build_dir"); target.AddIncludeDirAbsolute(schema_build_dir, true); // ENV diff --git a/buildcc/lib/target/cmake/common_target_src.cmake b/buildcc/lib/target/cmake/common_target_src.cmake index 130bda3f..e87f030e 100644 --- a/buildcc/lib/target/cmake/common_target_src.cmake +++ b/buildcc/lib/target/cmake/common_target_src.cmake @@ -56,5 +56,6 @@ set(COMMON_TARGET_SRCS # Target src/target/target.cpp src/target/build.cpp + src/target/tasks.cpp include/target/target.h ) diff --git a/buildcc/lib/target/cmake/mock_target.cmake b/buildcc/lib/target/cmake/mock_target.cmake index 6b7928e4..a648c983 100644 --- a/buildcc/lib/target/cmake/mock_target.cmake +++ b/buildcc/lib/target/cmake/mock_target.cmake @@ -5,7 +5,6 @@ add_library(mock_target STATIC mock/custom_generator/recheck_states.cpp # Target mocks - src/target/tasks.cpp mock/target/runner.cpp mock/target/recheck_states.cpp ) diff --git a/buildcc/lib/target/cmake/target.cmake b/buildcc/lib/target/cmake/target.cmake index b823b6cc..dc31284a 100644 --- a/buildcc/lib/target/cmake/target.cmake +++ b/buildcc/lib/target/cmake/target.cmake @@ -4,7 +4,6 @@ set(TARGET_SRCS src/custom_generator/recheck_states.cpp src/target/recheck_states.cpp - src/target/tasks.cpp ) if(${BUILDCC_BUILD_AS_SINGLE_LIB}) diff --git a/buildcc/lib/target/include/target/custom_generator.h b/buildcc/lib/target/include/target/custom_generator.h index 316290ea..c6630b9c 100644 --- a/buildcc/lib/target/include/target/custom_generator.h +++ b/buildcc/lib/target/include/target/custom_generator.h @@ -134,8 +134,9 @@ class CustomGenerator : public internal::BuilderInterface { * @param generate_cb User-defined generate callback to build outputs from the * provided inputs */ - void AddGenInfo(const std::string &id, const fs_unordered_set &inputs, - const fs_unordered_set &outputs, + void AddGenInfo(const std::string &id, + const std::unordered_set &inputs, + const std::unordered_set &outputs, const GenerateCb &generate_cb, std::shared_ptr blob_handler = nullptr); @@ -192,6 +193,11 @@ class CustomGenerator : public internal::BuilderInterface { void IdUpdated(); protected: + std::string ParsePattern(const std::string &pattern, + const std::unordered_map + &arguments = {}) const { + return command_.Construct(pattern, arguments); + } const env::Command &ConstCommand() const { return command_; } env::Command &RefCommand() { return command_; } diff --git a/buildcc/lib/target/include/target/file_generator.h b/buildcc/lib/target/include/target/file_generator.h index cc4b66b0..3a359d87 100644 --- a/buildcc/lib/target/include/target/file_generator.h +++ b/buildcc/lib/target/include/target/file_generator.h @@ -29,25 +29,23 @@ class FileGenerator : public CustomGenerator { /** * @brief Add absolute input path pattern to generator - * NOTE: We can use {gen_root_dir} and {gen_build_dir} in the + * NOTE: We can use {current_root_dir} and {current_build_dir} in the * absolute_input_pattern * * If `identifier` is supplied it is added to default arguments as a key * Example: fmt::format("{identifier}") -> "absolute_input_pattern" */ - void AddInput(const std::string &absolute_input_pattern, - const char *identifier = nullptr); + void AddInput(const std::string &absolute_input_pattern); /** * @brief Add absolute output path pattern to generator - * NOTE: We can use {gen_root_dir} and {gen_build_dir} in the + * NOTE: We can use {current_root_dir} and {current_build_dir} in the * absolute_output_pattern * * If `identifier` is supplied it is added to default arguments as a key * Example: fmt::format("{identifier}") -> "absolute_output_pattern" */ - void AddOutput(const std::string &absolute_output_pattern, - const char *identifier = nullptr); + void AddOutput(const std::string &absolute_output_pattern); /** * @brief Add a command_pattern that is fed to `Command::Execute` internally @@ -77,8 +75,8 @@ class FileGenerator : public CustomGenerator { private: // - internal::fs_unordered_set inputs_; - internal::fs_unordered_set outputs_; + std::unordered_set inputs_; + std::unordered_set outputs_; std::vector commands_; }; diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index cb9b1049..a795bda9 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -77,15 +77,12 @@ class Target : public internal::BuilderInterface, compile_pch_(*this), compile_object_(*this), link_target_(*this) { Initialize(); } - virtual ~Target() {} + virtual ~Target() = default; Target(const Target &target) = delete; // Builders void Build() override; - // Getters - env::TaskState GetTaskState() const noexcept { return task_state_; } - private: friend class internal::CompilePch; friend class internal::CompileObject; @@ -112,14 +109,7 @@ class Target : public internal::BuilderInterface, const std::vector ¤t_external_libs); // Tasks - void SetTaskStateFailure(); - int GetTaskStateAsInt() const noexcept { - return static_cast(task_state_); - } - - void StartTask(); void EndTask(); - tf::Task CheckStateTask(); void TaskDeps(); // Callbacks for unit tests @@ -151,8 +141,6 @@ class Target : public internal::BuilderInterface, // Task states tf::Task target_start_task_; tf::Task target_end_task_; - std::mutex task_state_mutex_; - env::TaskState task_state_{env::TaskState::SUCCESS}; }; typedef Target BaseTarget; diff --git a/buildcc/lib/target/include/target/template_generator.h b/buildcc/lib/target/include/target/template_generator.h index b22d49c0..6521be2d 100644 --- a/buildcc/lib/target/include/target/template_generator.h +++ b/buildcc/lib/target/include/target/template_generator.h @@ -17,6 +17,8 @@ #ifndef TARGET_TEMPLATE_GENERATOR_H_ #define TARGET_TEMPLATE_GENERATOR_H_ +#include + #include "target/custom_generator.h" namespace buildcc { @@ -27,8 +29,8 @@ class TemplateGenerator : public CustomGenerator { ~TemplateGenerator() override = default; TemplateGenerator(const TemplateGenerator &) = delete; - void AddTemplate(const fs::path &input_filename, - const fs::path &output_filename); + void AddTemplate(std::string_view absolute_input_pattern, + std::string_view absolute_output_pattern); std::string Parse(const std::string &pattern) const; /** @@ -47,8 +49,8 @@ class TemplateGenerator : public CustomGenerator { private: struct TemplateInfo { - fs::path input; - fs::path output; + std::string input_pattern; + std::string output_pattern; }; private: diff --git a/buildcc/lib/target/src/custom_generator/custom_generator.cpp b/buildcc/lib/target/src/custom_generator/custom_generator.cpp index c488a54b..815aba79 100644 --- a/buildcc/lib/target/src/custom_generator/custom_generator.cpp +++ b/buildcc/lib/target/src/custom_generator/custom_generator.cpp @@ -19,6 +19,10 @@ namespace { constexpr const char *const kGenerateTaskName = "Generate"; +constexpr const char *const kProjectRootDirName = "project_root_dir"; +constexpr const char *const kProjectBuildDirName = "project_build_dir"; +constexpr const char *const kCurrentRootDirName = "current_root_dir"; +constexpr const char *const kCurrentBuildDirName = "current_build_dir"; } // namespace @@ -42,8 +46,9 @@ CustomGenerator::Get(const std::string &file_identifier) const { } void CustomGenerator::AddGenInfo( - const std::string &id, const fs_unordered_set &inputs, - const fs_unordered_set &outputs, const GenerateCb &generate_cb, + const std::string &id, const std::unordered_set &inputs, + const std::unordered_set &outputs, + const GenerateCb &generate_cb, std::shared_ptr blob_handler) { env::assert_fatal(user_.gen_info_map.find(id) == user_.gen_info_map.end(), fmt::format("Duplicate id {} detected", id)); @@ -51,15 +56,11 @@ void CustomGenerator::AddGenInfo( UserGenInfo schema; for (const auto &i : inputs) { - fs::path input = - internal::Path::CreateNewPath(command_.Construct(path_as_string(i))) - .GetPathname(); + fs::path input = string_as_path(command_.Construct(i)); schema.inputs.emplace(std::move(input)); } for (const auto &o : outputs) { - fs::path output = - internal::Path::CreateNewPath(command_.Construct(path_as_string(o))) - .GetPathname(); + fs::path output = string_as_path(command_.Construct(o)); schema.outputs.emplace(std::move(output)); } schema.generate_cb = generate_cb; @@ -109,10 +110,10 @@ void CustomGenerator::Initialize() { // fs::create_directories(env_.GetTargetBuildDir()); command_.AddDefaultArguments({ - {"project_root_dir", path_as_string(Project::GetRootDir())}, - {"project_build_dir", path_as_string(Project::GetBuildDir())}, - {"gen_root_dir", path_as_string(env_.GetTargetRootDir())}, - {"gen_build_dir", path_as_string(env_.GetTargetBuildDir())}, + {kProjectRootDirName, path_as_string(Project::GetRootDir())}, + {kProjectBuildDirName, path_as_string(Project::GetBuildDir())}, + {kCurrentRootDirName, path_as_string(env_.GetTargetRootDir())}, + {kCurrentBuildDirName, path_as_string(env_.GetTargetBuildDir())}, }); // diff --git a/buildcc/lib/target/src/generator/file_generator.cpp b/buildcc/lib/target/src/generator/file_generator.cpp index 1362ed32..9f60aa96 100644 --- a/buildcc/lib/target/src/generator/file_generator.cpp +++ b/buildcc/lib/target/src/generator/file_generator.cpp @@ -95,37 +95,18 @@ bool FileGeneratorGenerateCb(const buildcc::CustomGeneratorContext &ctx) { namespace buildcc { -void FileGenerator::AddInput(const std::string &absolute_input_pattern, - const char *identifier) { - std::string absolute_input_string = - RefCommand().Construct(absolute_input_pattern); - const auto absolute_input_path = - internal::Path::CreateNewPath(absolute_input_string); - inputs_.insert(absolute_input_path.GetPathname()); - - if (identifier != nullptr) { - AddPattern(identifier, absolute_input_path.GetPathAsString()); - } +void FileGenerator::AddInput(const std::string &absolute_input_pattern) { + inputs_.emplace(absolute_input_pattern); } -void FileGenerator::AddOutput(const std::string &absolute_output_pattern, - const char *identifier) { - std::string absolute_output_string = - RefCommand().Construct(absolute_output_pattern); - const auto absolute_output_path = - internal::Path::CreateNewPath(absolute_output_string); - outputs_.insert(absolute_output_path.GetPathname()); - - if (identifier != nullptr) { - AddPattern(identifier, absolute_output_path.GetPathAsString()); - } +void FileGenerator::AddOutput(const std::string &absolute_output_pattern) { + outputs_.emplace(absolute_output_pattern); } void FileGenerator::AddCommand( const std::string &command_pattern, const std::unordered_map &arguments) { - std::string constructed_command = - RefCommand().Construct(command_pattern, arguments); + std::string constructed_command = ParsePattern(command_pattern, arguments); commands_.emplace_back(std::move(constructed_command)); } diff --git a/buildcc/lib/target/src/generator/template_generator.cpp b/buildcc/lib/target/src/generator/template_generator.cpp index e7c059c0..4c6f2a1e 100644 --- a/buildcc/lib/target/src/generator/template_generator.cpp +++ b/buildcc/lib/target/src/generator/template_generator.cpp @@ -44,20 +44,16 @@ bool template_generate_cb(const buildcc::CustomGeneratorContext &ctx) { namespace buildcc { -void TemplateGenerator::AddTemplate(const fs::path &input_filename, - const fs::path &output_filename) { +void TemplateGenerator::AddTemplate(std::string_view absolute_input_pattern, + std::string_view absolute_output_pattern) { TemplateInfo info; - info.input = internal::Path::CreateNewPath( - RefCommand().Construct(path_as_string(input_filename))) - .GetPathname(); - info.output = internal::Path::CreateNewPath( - RefCommand().Construct(path_as_string(output_filename))) - .GetPathname(); + info.input_pattern = absolute_input_pattern; + info.output_pattern = absolute_output_pattern; template_infos_.emplace_back(std::move(info)); } std::string TemplateGenerator::Parse(const std::string &pattern) const { - return ConstCommand().Construct(pattern); + return ParsePattern(pattern); } /** @@ -67,9 +63,11 @@ std::string TemplateGenerator::Parse(const std::string &pattern) const { */ void TemplateGenerator::Build() { for (const auto &info : template_infos_) { - std::string name = - info.input.lexically_relative(Project::GetRootDir()).string(); - AddGenInfo(name, {info.input}, {info.output}, template_generate_cb); + std::string name = string_as_path(ParsePattern(info.input_pattern)) + .lexically_relative(Project::GetRootDir()) + .string(); + AddGenInfo(name, {info.input_pattern}, {info.output_pattern}, + template_generate_cb); } this->CustomGenerator::Build(); } diff --git a/buildcc/lib/target/src/target/build.cpp b/buildcc/lib/target/src/target/build.cpp index 43a1572e..b1155dec 100644 --- a/buildcc/lib/target/src/target/build.cpp +++ b/buildcc/lib/target/src/target/build.cpp @@ -97,10 +97,6 @@ void Target::Build() { // Load the serialized file (void)serialization_.LoadFromFile(); - // Target State Tasks - StartTask(); - EndTask(); - // PCH Compile if (state_.ContainsPch()) { command_.AddDefaultArguments({ @@ -119,6 +115,9 @@ void Target::Build() { }); } + // Target State Tasks + EndTask(); + // Compile Command compile_object_.CacheCompileCommands(); compile_object_.Task(); diff --git a/buildcc/lib/target/src/target/tasks.cpp b/buildcc/lib/target/src/target/tasks.cpp index 7f46c99f..98ba8f9c 100644 --- a/buildcc/lib/target/src/target/tasks.cpp +++ b/buildcc/lib/target/src/target/tasks.cpp @@ -36,39 +36,7 @@ constexpr const char *const kLinkTaskName = "Target"; } // namespace -namespace buildcc { - -void Target::SetTaskStateFailure() { - std::lock_guard guard(task_state_mutex_); - task_state_ = env::TaskState::FAILURE; -} - -tf::Task Target::CheckStateTask() { - // NOTE, For now we only have 2 states - // 0 -> SUCCESS - // 1 -> FAILURE - // * When more states are added make sure to handle them explicitly - return tf_.emplace([&]() { return GetTaskStateAsInt(); }) - .name(kCheckTaskName); -} - -void Target::StartTask() { - // Return 0 for success - // Return 1 for failure - target_start_task_ = tf_.emplace([&]() { - switch (env::get_task_state()) { - case env::TaskState::SUCCESS: - break; - default: - SetTaskStateFailure(); - break; - }; - return GetTaskStateAsInt(); - }); - target_start_task_.name(kStartTaskName); -} - -} // namespace buildcc +namespace buildcc {} // namespace buildcc namespace buildcc::internal { @@ -78,11 +46,15 @@ namespace buildcc::internal { // 3. Successfully compiled sources are added to `compiled_pch_files_` void CompilePch::Task() { task_ = target_.tf_.emplace([&](tf::Subflow &subflow) { + if (env::get_task_state() != env::TaskState::SUCCESS) { + return; + } + try { BuildCompile(); target_.serialization_.UpdatePchCompiled(target_.user_); } catch (...) { - target_.SetTaskStateFailure(); + env::set_task_state(env::TaskState::FAILURE); } // For Graph generation @@ -107,6 +79,10 @@ void CompilePch::Task() { // serialization schema void CompileObject::Task() { compile_task_ = target_.tf_.emplace([&](tf::Subflow &subflow) { + if (env::get_task_state() != env::TaskState::SUCCESS) { + return; + } + std::vector selected_source_files; std::vector selected_dummy_source_files; @@ -127,7 +103,7 @@ void CompileObject::Task() { env::assert_fatal(success, "Could not compile source"); target_.serialization_.AddSource(s); } catch (...) { - target_.SetTaskStateFailure(); + env::set_task_state(env::TaskState::FAILURE); } }) .name(name); @@ -140,7 +116,7 @@ void CompileObject::Task() { (void)subflow.placeholder().name(name); } } catch (...) { - target_.SetTaskStateFailure(); + env::set_task_state(env::TaskState::FAILURE); } }); compile_task_.name(kCompileTaskName); @@ -152,10 +128,13 @@ void CompileObject::Task() { // 3. Successfully linking the target sets link state void LinkTarget::Task() { task_ = target_.tf_.emplace([&]() { + if (env::get_task_state() != env::TaskState::SUCCESS) { + return; + } try { BuildLink(); } catch (...) { - target_.SetTaskStateFailure(); + env::set_task_state(env::TaskState::FAILURE); } }); task_.name(kLinkTaskName); @@ -174,31 +153,18 @@ void Target::EndTask() { fmt::format("Store failed for {}", GetName())); state_.BuildCompleted(); } catch (...) { - SetTaskStateFailure(); + env::set_task_state(env::TaskState::FAILURE); } } - - // Update env task state - if (task_state_ != env::TaskState::SUCCESS) { - env::set_task_state(GetTaskState()); - } }); target_end_task_.name(kEndTaskName); } void Target::TaskDeps() { if (state_.ContainsPch()) { - target_start_task_.precede(compile_pch_.GetTask(), target_end_task_); - tf::Task pch_check_state_task = CheckStateTask(); - compile_pch_.GetTask().precede(pch_check_state_task); - pch_check_state_task.precede(compile_object_.GetTask(), target_end_task_); - } else { - target_start_task_.precede(compile_object_.GetTask(), target_end_task_); + compile_pch_.GetTask().precede(compile_object_.GetTask()); } - - tf::Task object_check_state_task = CheckStateTask(); - compile_object_.GetTask().precede(object_check_state_task); - object_check_state_task.precede(link_target_.GetTask(), target_end_task_); + compile_object_.GetTask().precede(link_target_.GetTask()); link_target_.GetTask().precede(target_end_task_); } diff --git a/buildcc/lib/target/test/target/data/template/default_values.txt.in b/buildcc/lib/target/test/target/data/template/default_values.txt.in index 9ea1d25f..fa8699fd 100644 --- a/buildcc/lib/target/test/target/data/template/default_values.txt.in +++ b/buildcc/lib/target/test/target/data/template/default_values.txt.in @@ -1,4 +1,4 @@ -{gen_root_dir} -{gen_build_dir} +{current_root_dir} +{current_build_dir} {project_root_dir} {project_build_dir} diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp index ea3eef74..3c919d30 100644 --- a/buildcc/lib/target/test/target/test_custom_generator.cpp +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -35,9 +35,9 @@ static bool BasicGenerateCb(const buildcc::CustomGeneratorContext &ctx) { TEST(CustomGeneratorTestGroup, Basic) { buildcc::CustomGenerator cgen("basic", ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, BasicGenerateCb); cgen.Build(); @@ -65,8 +65,9 @@ TEST(CustomGeneratorTestGroup, Basic) { TEST(CustomGeneratorTestGroup, Basic_Failure) { buildcc::CustomGenerator cgen("basic_failure", ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, {}, BasicGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, {}, + BasicGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, BasicGenerateCb); cgen.Build(); @@ -87,9 +88,9 @@ TEST(CustomGeneratorTestGroup, Basic_Failure) { TEST(CustomGeneratorTestGroup, Basic_Group) { buildcc::CustomGenerator cgen("basic_group", ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, BasicGenerateCb); cgen.AddGroup("grouped_id1_and_id2", {"id1", "id2"}); cgen.Build(); @@ -118,9 +119,9 @@ TEST(CustomGeneratorTestGroup, Basic_Group) { TEST(CustomGeneratorTestGroup, Basic_Group_Dependency) { buildcc::CustomGenerator cgen("basic_group_dependency", ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, BasicGenerateCb); cgen.AddGroup("grouped_id1_and_id2", {"id1", "id2"}, [](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); @@ -151,9 +152,9 @@ TEST(CustomGeneratorTestGroup, Basic_Group_Dependency) { TEST(CustomGeneratorTestGroup, Basic_Group_DependencyFailure) { buildcc::CustomGenerator cgen("basic_group_dependency_failure", ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, BasicGenerateCb); cgen.AddGroup("grouped_id1_and_id2", {"id1", "id2"}, [](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); @@ -189,9 +190,9 @@ bool SuccessCb(const buildcc::CustomGeneratorContext &ctx) { // ungrouped task TEST(CustomGeneratorTestGroup, Basic_Group_DependencyFailure2) { buildcc::CustomGenerator cgen("basic_group_dependency_failure2", ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, FailureCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, SuccessCb); + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FailureCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, SuccessCb); cgen.AddGroup("grouped_id2", {"id2"}); cgen.AddDependencyCb([&](auto &&task_map) { task_map.at("id1").precede(task_map.at("grouped_id2")); @@ -260,9 +261,9 @@ TEST(CustomGeneratorTestGroup, Basic_ProperDependency_GoodCase) { rebuild_value = false; buildcc::CustomGenerator cgen("basic_proper_dependency_good_case", ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, ProperDependency1); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, ProperDependency1); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, ProperDependency2); cgen.AddDependencyCb( [](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); @@ -290,9 +291,9 @@ TEST(CustomGeneratorTestGroup, Basic_ProperDependency_BadCase) { rebuild_value = false; buildcc::CustomGenerator cgen("basic_proper_dependency_bad_case", ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, ProperDependency1); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.cpp"}, {}, + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, ProperDependency1); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, ProperDependency2); cgen.AddDependencyCb( [](auto &&task_map) { task_map.at("id2").precede(task_map.at("id1")); }); @@ -317,9 +318,9 @@ TEST(CustomGeneratorTestGroup, Basic_ProperDependency_BadCase) { TEST(CustomGeneratorTestGroup, DefaultArgumentUsage) { buildcc::CustomGenerator cgen("default_argument_usage", ""); cgen.AddPatterns({ - {"dummy_main_c", "{gen_root_dir}/dummy_main.c"}, - {"dummy_main_o", "{gen_build_dir}/dummy_main.o"}, - {"dummy_main_cpp", "{gen_root_dir}/dummy_main.cpp"}, + {"dummy_main_c", "{current_root_dir}/dummy_main.c"}, + {"dummy_main_o", "{current_build_dir}/dummy_main.o"}, + {"dummy_main_cpp", "{current_root_dir}/dummy_main.cpp"}, }); cgen.AddGenInfo("id1", {"{dummy_main_c}"}, {"{dummy_main_o}"}, BasicGenerateCb); @@ -420,10 +421,10 @@ TEST(CustomGeneratorTestGroup, AddDependency_BasicCheck) { constexpr const char *const kGenName = "add_dependency_basic_check"; { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, Dep2Cb); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/dummy_main.o"}, Dep1Cb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, Dep2Cb); + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, Dep1Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -460,9 +461,10 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep) { constexpr const char *const kGenName = "add_dependency_file_dep"; { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, + FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -488,9 +490,10 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, + FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -509,9 +512,10 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { // Same, no change { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, + FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -533,7 +537,8 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { // sets dirty_ == true { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, + FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -555,9 +560,10 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { // Added { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, + FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -586,9 +592,10 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.o"}, {}, FileDep2Cb); + cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, + FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -617,10 +624,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { constexpr const char *const kGenName = "real_generator_basic"; { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -639,9 +646,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, {}, + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, {}, + RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, {}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, {}, RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -670,10 +678,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { constexpr const char *const kGenName = "real_generator_remove_and_add"; { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -697,10 +705,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { // Same, no change { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.Build(); buildcc::m::CustomGeneratorRunner(cgen); @@ -720,8 +728,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { // Map Removed { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.Build(); @@ -742,10 +750,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { // Map Added Failure { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.AddDependencyCb([](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); @@ -772,10 +780,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { // Map Added Success { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_root_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.Build(); buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); @@ -806,10 +814,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { buildcc::env::save_file( (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); - cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, + {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); cgen.AddDependencyCb([](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); @@ -842,10 +850,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { buildcc::env::save_file( (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); - cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, + {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); cgen.AddDependencyCb([](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); @@ -879,10 +887,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { buildcc::env::save_file( (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); - cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, + {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -917,10 +925,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { .time_since_epoch() .count()); - cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, + {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -950,10 +958,11 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_build_dir}/dummy_main.c"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{gen_build_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/rename_dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, + {"{current_build_dir}/rename_dummy_main.o"}, + RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -1010,8 +1019,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_BasicBlobRecheck) { constexpr const char *const kGenName = "real_generator_basic_blob_recheck"; { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb, + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb, std::make_shared(12)); cgen.Build(); @@ -1028,8 +1037,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_BasicBlobRecheck) { // Rebuild { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{gen_root_dir}/dummy_main.cpp"}, - {"{gen_build_dir}/dummy_main.o"}, RealGenerateCb, + cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb, std::make_shared(200)); cgen.Build(); diff --git a/buildcc/lib/target/test/target/test_file_generator.cpp b/buildcc/lib/target/test/target/test_file_generator.cpp index f6fc257e..278aa7a6 100644 --- a/buildcc/lib/target/test/target/test_file_generator.cpp +++ b/buildcc/lib/target/test/target/test_file_generator.cpp @@ -35,10 +35,10 @@ TEST(FileGeneratorTestGroup, Generator_Build) { {"compiler", "gcc"}, }); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c"); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); @@ -54,9 +54,11 @@ TEST(FileGeneratorTestGroup, Generator_Identifier) { generator.AddPatterns({ {"compiler", "gcc"}, }); + generator.AddPattern("dummy_main_c", "{current_root_dir}/dummy_main.c"); + generator.AddPattern("dummy_main_exe", "{current_build_dir}/dummy_main.exe"); - generator.AddInput("{gen_root_dir}/dummy_main.c", "dummy_main_c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe", "dummy_main_exe"); + generator.AddInput("{dummy_main_c}"); + generator.AddOutput("{dummy_main_exe}"); generator.AddCommand("{compiler} -o {dummy_main_exe} {dummy_main_c}"); buildcc::env::m::CommandExpect_Execute(1, true); @@ -70,10 +72,10 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild) { constexpr const char *const NAME = "Rebuild"; { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c", + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c", { {"compiler", "gcc"}, }); @@ -85,10 +87,10 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild) { { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c", + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c", { {"compiler", "gcc"}, }); @@ -105,10 +107,10 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild_Inputs) { { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/new_source.cpp"); - generator.AddOutput("{gen_build_dir}/new_source.exe"); - generator.AddCommand("gcc -o {gen_build_dir}/new_source.exe " - "{gen_root_dir}/new_source.cpp"); + generator.AddInput("{current_root_dir}/new_source.cpp"); + generator.AddOutput("{current_build_dir}/new_source.exe"); + generator.AddCommand("gcc -o {current_build_dir}/new_source.exe " + "{current_root_dir}/new_source.cpp"); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); @@ -119,9 +121,9 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild_Inputs) { // Removed { buildcc::FileGenerator generator(NAME, ""); - generator.AddOutput("{gen_build_dir}/new_source.exe"); - generator.AddCommand("gcc -o {gen_build_dir}/new_source.exe " - "{gen_root_dir}/new_source.cpp"); + generator.AddOutput("{current_build_dir}/new_source.exe"); + generator.AddCommand("gcc -o {current_build_dir}/new_source.exe " + "{current_root_dir}/new_source.cpp"); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); @@ -132,10 +134,10 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild_Inputs) { // Added { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/new_source.cpp"); - generator.AddOutput("{gen_build_dir}/new_source.cpp.exe"); - generator.AddCommand("gcc -o {gen_build_dir}/new_source.cpp.exe " - "{gen_root_dir}/new_source.cpp"); + generator.AddInput("{current_root_dir}/new_source.cpp"); + generator.AddOutput("{current_build_dir}/new_source.cpp.exe"); + generator.AddCommand("gcc -o {current_build_dir}/new_source.cpp.exe " + "{current_root_dir}/new_source.cpp"); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); @@ -151,10 +153,10 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild_Inputs) { // Updated { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/new_source.cpp"); - generator.AddOutput("{gen_build_dir}/new_source.cpp.exe"); - generator.AddCommand("gcc -o {gen_build_dir}/new_source.cpp.exe " - "{gen_root_dir}/new_source.cpp"); + generator.AddInput("{current_root_dir}/new_source.cpp"); + generator.AddOutput("{current_build_dir}/new_source.cpp.exe"); + generator.AddCommand("gcc -o {current_build_dir}/new_source.cpp.exe " + "{current_root_dir}/new_source.cpp"); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); @@ -168,10 +170,10 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild_Outputs) { constexpr const char *const NAME = "Rebuild_Outputs"; { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c", + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c", { {"compiler", "gcc"}, }); @@ -183,9 +185,9 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild_Outputs) { { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c", + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c", { {"compiler", "gcc"}, }); @@ -197,10 +199,10 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild_Outputs) { { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c", + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c", { {"compiler", "gcc"}, }); @@ -217,10 +219,10 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild_Commands) { constexpr const char *const NAME = "Rebuild_Commands"; { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c", + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c", { {"compiler", "gcc"}, }); @@ -232,9 +234,9 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild_Commands) { { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} {gen_root_dir}/dummy_main.c", + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} {current_root_dir}/dummy_main.c", { {"compiler", "gcc"}, }); @@ -246,10 +248,10 @@ TEST(FileGeneratorTestGroup, Generator_Rebuild_Commands) { { buildcc::FileGenerator generator(NAME, ""); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("gcc -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("gcc -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c"); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); @@ -283,10 +285,10 @@ TEST(FileGeneratorTestGroup, Generator_FailedEnvTaskState) { {"compiler", "gcc"}, }); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c"); generator.Build(); buildcc::m::CustomGeneratorRunner(generator); @@ -304,10 +306,10 @@ TEST(FileGeneratorTestGroup, Generator_FailedGenerateConvert) { {"compiler", "gcc"}, }); - generator.AddInput("{gen_root_dir}/this_file_does_not_exist.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); + generator.AddInput("{current_root_dir}/this_file_does_not_exist.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c"); generator.Build(); buildcc::m::CustomGeneratorRunner(generator); @@ -327,10 +329,10 @@ TEST(FileGeneratorTestGroup, Generator_FailedGenerateCommand) { {"compiler", "gcc"}, }); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c"); buildcc::env::m::CommandExpect_Execute(1, false); generator.Build(); @@ -352,10 +354,10 @@ TEST(FileGeneratorTestGroup, Generator_FailedStore) { {"compiler", "gcc"}, }); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c"); buildcc::env::m::CommandExpect_Execute(1, true); generator.Build(); @@ -380,10 +382,10 @@ TEST(FileGeneratorTestGroup, FailedEnvTaskState_Rebuild) { {"compiler", "gcc"}, }); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c"); generator.Build(); buildcc::m::CustomGeneratorRunner(generator); @@ -400,10 +402,10 @@ TEST(FileGeneratorTestGroup, FailedEnvTaskState_Rebuild) { {"compiler", "gcc"}, }); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c"); generator.Build(); buildcc::env::m::CommandExpect_Execute(1, true); @@ -423,10 +425,10 @@ TEST(FileGeneratorTestGroup, FailedGenerateCommand_Rebuild) { {"compiler", "gcc"}, }); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c"); buildcc::env::m::CommandExpect_Execute(1, false); generator.Build(); @@ -444,10 +446,10 @@ TEST(FileGeneratorTestGroup, FailedGenerateCommand_Rebuild) { {"compiler", "gcc"}, }); - generator.AddInput("{gen_root_dir}/dummy_main.c"); - generator.AddOutput("{gen_build_dir}/dummy_main.exe"); - generator.AddCommand("{compiler} -o {gen_build_dir}/dummy_main.exe " - "{gen_root_dir}/dummy_main.c"); + generator.AddInput("{current_root_dir}/dummy_main.c"); + generator.AddOutput("{current_build_dir}/dummy_main.exe"); + generator.AddCommand("{compiler} -o {current_build_dir}/dummy_main.exe " + "{current_root_dir}/dummy_main.c"); buildcc::m::CustomGeneratorExpect_IdAdded(1, &generator); buildcc::env::m::CommandExpect_Execute(1, true); diff --git a/buildcc/lib/target/test/target/test_target_failure_states.cpp b/buildcc/lib/target/test/target/test_target_failure_states.cpp index f7d813f5..114ec908 100644 --- a/buildcc/lib/target/test/target/test_target_failure_states.cpp +++ b/buildcc/lib/target/test/target/test_target_failure_states.cpp @@ -40,7 +40,7 @@ TEST(TargetTestFailureStates, StartTaskEnvFailure) { target.Build(); buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } TEST(TargetTestFailureStates, CompilePchFailure) { @@ -55,7 +55,7 @@ TEST(TargetTestFailureStates, CompilePchFailure) { buildcc::env::m::CommandExpect_Execute(1, false); // PCH compile buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } TEST(TargetTestFailureStates, CompileObjectFailure) { @@ -72,7 +72,7 @@ TEST(TargetTestFailureStates, CompileObjectFailure) { buildcc::env::m::CommandExpect_Execute(1, true); // compile buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } TEST(TargetTestFailureStates, CompileObject_FileNotFoundFailure) { @@ -85,7 +85,7 @@ TEST(TargetTestFailureStates, CompileObject_FileNotFoundFailure) { target.Build(); buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } TEST(TargetTestFailureStates, LinkTargetFailure) { @@ -101,7 +101,7 @@ TEST(TargetTestFailureStates, LinkTargetFailure) { buildcc::env::m::CommandExpect_Execute(1, false); // link buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } TEST(TargetTestFailureStates, EndTaskStoreFailure) { @@ -119,7 +119,7 @@ TEST(TargetTestFailureStates, EndTaskStoreFailure) { buildcc::env::m::CommandExpect_Execute(1, true); // link buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } // TODO, Test failure rebuilds! @@ -138,7 +138,7 @@ TEST(TargetTestFailureStates, StartTaskEnvFailure_Rebuild) { target.Build(); buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); CHECK_FALSE(target.IsBuilt()); } @@ -157,7 +157,7 @@ TEST(TargetTestFailureStates, StartTaskEnvFailure_Rebuild) { buildcc::env::m::CommandExpect_Execute(1, true); // link buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::SUCCESS); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); CHECK_TRUE(target.IsBuilt()); } } @@ -177,7 +177,7 @@ TEST(TargetTestFailureStates, CompilePchFailure_Rebuild) { buildcc::env::m::CommandExpect_Execute(1, false); // PCH compile buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } // Reset @@ -201,7 +201,7 @@ TEST(TargetTestFailureStates, CompilePchFailure_Rebuild) { buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::SUCCESS); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } } @@ -222,7 +222,7 @@ TEST(TargetTestFailureStates, CompileObjectFailure_Rebuild) { buildcc::env::m::CommandExpect_Execute(1, true); // compile buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } // Reset @@ -253,7 +253,7 @@ TEST(TargetTestFailureStates, CompileObjectFailure_Rebuild) { buildcc::env::m::CommandExpect_Execute(1, true); // link buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::SUCCESS); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } } @@ -272,7 +272,7 @@ TEST(TargetTestFailureStates, LinkTargetFailure_Rebuild) { buildcc::env::m::CommandExpect_Execute(1, false); // link buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::FAILURE); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } // Reset @@ -290,7 +290,7 @@ TEST(TargetTestFailureStates, LinkTargetFailure_Rebuild) { buildcc::env::m::CommandExpect_Execute(1, true); // link buildcc::m::TargetRunner(target); - CHECK(target.GetTaskState() == buildcc::env::TaskState::SUCCESS); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } } diff --git a/buildcc/lib/target/test/target/test_target_pch.cpp b/buildcc/lib/target/test/target/test_target_pch.cpp index 4278c40c..64fdbd8b 100644 --- a/buildcc/lib/target/test/target/test_target_pch.cpp +++ b/buildcc/lib/target/test/target/test_target_pch.cpp @@ -286,6 +286,29 @@ TEST(TargetPchTestGroup, Target_AddPchObjectFlag_Build) { mock().checkExpectations(); } +TEST(TargetPchTestGroup, Target_BadPch) { + constexpr const char *const NAME = "Target_BadPch.exe"; + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddPch("pch/pch_header_2.h"); + + buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE); + + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_FALSE(exists); + + buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); + + // Save file + exists = fs::exists(target.GetPchHeaderPath()); + CHECK_FALSE(exists); + + mock().checkExpectations(); +} + int main(int ac, char **av) { const fs::path target_source_intermediate_path = fs::path(BUILD_TARGET_PCH_INTERMEDIATE_DIR) / gcc.GetName(); diff --git a/buildcc/lib/target/test/target/test_target_source.cpp b/buildcc/lib/target/test/target/test_target_source.cpp index 2d09ab04..a7b6ba11 100644 --- a/buildcc/lib/target/test/target/test_target_source.cpp +++ b/buildcc/lib/target/test/target/test_target_source.cpp @@ -103,7 +103,7 @@ TEST(TargetTestSourceGroup, Target_Build_SourceCompile) { buildcc::env::m::CommandExpect_Execute(1, true); // link buildcc::m::TargetRunner(simple); - CHECK(simple.GetTaskState() == buildcc::env::TaskState::SUCCESS); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); mock().checkExpectations(); diff --git a/buildcc/lib/target/test/target/test_template_generator.cpp b/buildcc/lib/target/test/target/test_template_generator.cpp index f84193fc..451c76ae 100644 --- a/buildcc/lib/target/test/target/test_template_generator.cpp +++ b/buildcc/lib/target/test/target/test_template_generator.cpp @@ -47,10 +47,10 @@ TEST(TemplateGeneratorTestGroup, Basic_InputParse) { {"hello", "Hello"}, {"world", "World"}, }); - generator.AddTemplate("{gen_root_dir}/template/default_values.txt.in", - "{gen_build_dir}/default_values.txt"); - generator.AddTemplate("{gen_root_dir}/template/hello_world.txt.in", - "{gen_build_dir}/hello_world.txt"); + generator.AddTemplate("{current_root_dir}/template/default_values.txt.in", + "{current_build_dir}/default_values.txt"); + generator.AddTemplate("{current_root_dir}/template/hello_world.txt.in", + "{current_build_dir}/hello_world.txt"); generator.Build(); buildcc::m::CustomGeneratorRunner(generator); @@ -65,8 +65,8 @@ TEST(TemplateGeneratorTestGroup, Basic_SaveFailure) { fs::create_directories(generator.GetBuildDir() / "default_values.txt"); - generator.AddTemplate("{gen_root_dir}/template/default_values.txt.in", - "{gen_build_dir}/default_values.txt"); + generator.AddTemplate("{current_root_dir}/template/default_values.txt.in", + "{current_build_dir}/default_values.txt"); generator.Build(); buildcc::m::CustomGeneratorRunner(generator); @@ -81,8 +81,8 @@ TEST(TemplateGeneratorTestGroup, Basic_LoadFailure) { fs::create_directories(generator.GetBuildDir() / "default_values.txt.in"); - generator.AddTemplate("{gen_build_dir}/default_values.txt.in", - "{gen_build_dir}/default_values.txt"); + generator.AddTemplate("{current_build_dir}/default_values.txt.in", + "{current_build_dir}/default_values.txt"); generator.Build(); buildcc::m::CustomGeneratorRunner(generator); diff --git a/buildcc/schema/include/schema/path.h b/buildcc/schema/include/schema/path.h index 1810d3d1..a98c3d2f 100644 --- a/buildcc/schema/include/schema/path.h +++ b/buildcc/schema/include/schema/path.h @@ -20,8 +20,6 @@ #include #include #include - -// The Path class defined below is meant to be used with Sets #include // Env @@ -44,7 +42,6 @@ class Path { * @param pathname * @return Path */ - // TODO, Discuss if we should return `std::optional` instead of asserting static Path CreateExistingPath(const fs::path &pathname) { std::error_code errcode; uint64_t last_write_timestamp = @@ -109,7 +106,7 @@ class Path { private: explicit Path(const fs::path &pathname, std::uint64_t last_write_timestamp) : pathname_(pathname), last_write_timestamp_(last_write_timestamp) { - pathname_.make_preferred(); + pathname_.lexically_normal().make_preferred(); } std::string Quote(const std::string &str) const { @@ -140,8 +137,8 @@ class PathHash { size_t operator()(const fs::path &p) const { return fs::hash_value(p); } }; -typedef std::unordered_set path_unordered_set; -typedef std::unordered_set fs_unordered_set; +using path_unordered_set = std::unordered_set; +using fs_unordered_set = std::unordered_set; inline std::vector path_schema_convert(const std::vector &path_list, @@ -182,7 +179,15 @@ inline std::string path_as_string(const fs::path &p) { return internal::Path::CreateNewPath(p).GetPathAsString(); } -typedef internal::fs_unordered_set fs_unordered_set; +inline std::string path_as_display_string(const fs::path &p) { + return internal::Path::CreateNewPath(p).GetPathAsStringForDisplay(); +} + +inline fs::path string_as_path(const std::string &str) { + return internal::Path::CreateNewPath(str).GetPathname(); +} + +using fs_unordered_set = internal::fs_unordered_set; } // namespace buildcc @@ -191,9 +196,8 @@ typedef internal::fs_unordered_set fs_unordered_set; template <> struct fmt::formatter : formatter { template auto format(const fs::path &p, FormatContext &ctx) { - return formatter::format( - buildcc::internal::Path::CreateNewPath(p).GetPathAsStringForDisplay(), - ctx); + return formatter::format(buildcc::path_as_display_string(p), + ctx); } }; diff --git a/example/hybrid/dep_chaining/build.cpp b/example/hybrid/dep_chaining/build.cpp index 33f5bcff..1195f989 100644 --- a/example/hybrid/dep_chaining/build.cpp +++ b/example/hybrid/dep_chaining/build.cpp @@ -97,15 +97,19 @@ static void c_target_cb(BaseTarget &ctarget, const FileGenerator &c_generator) { } static void cpp_generator_cb(FileGenerator &generator) { - generator.AddOutput("{gen_build_dir}/main.cpp", "main_cpp"); - generator.AddCommand("python3 {gen_root_dir}/python/gen.py --source_type cpp " - "--destination {main_cpp}"); + generator.AddPattern("main_cpp", "{current_build_dir}/main.cpp"); + generator.AddOutput("{main_cpp}"); + generator.AddCommand( + "python3 {current_root_dir}/python/gen.py --source_type cpp " + "--destination {main_cpp}"); generator.Build(); } static void c_generator_cb(FileGenerator &generator) { - generator.AddOutput("{gen_build_dir}/main.c", "main_c"); - generator.AddCommand("python3 {gen_root_dir}/python/gen.py --source_type c " - "--destination {main_c}"); + generator.AddPattern("main_c", "{current_build_dir}/main.c"); + generator.AddOutput("{main_c}"); + generator.AddCommand( + "python3 {current_root_dir}/python/gen.py --source_type c " + "--destination {main_c}"); generator.Build(); } From 15f2908fbfdec90f6ad865b179efb3a3d490706d Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 15 Oct 2022 21:43:06 -0700 Subject: [PATCH 24/35] [Cleanup] Remove Lock APIs (#217) --- .../target/include/target/api/target_getter.h | 1 - .../lib/target/include/target/target_info.h | 1 - buildcc/lib/target/src/api/deps_api.cpp | 2 - buildcc/lib/target/src/api/flag_api.cpp | 8 -- buildcc/lib/target/src/api/include_api.cpp | 2 - buildcc/lib/target/src/api/lib_api.cpp | 3 - buildcc/lib/target/src/api/pch_api.cpp | 1 - buildcc/lib/target/src/api/source_api.cpp | 1 - buildcc/lib/target/src/api/sync_api.cpp | 2 - buildcc/lib/target/src/api/target_getter.cpp | 9 -- buildcc/lib/target/src/target/build.cpp | 3 - .../target/src/target_info/target_info.cpp | 4 - buildcc/lib/target/test/target/CMakeLists.txt | 6 - buildcc/lib/target/test/target/constants.h.in | 2 - .../target/test/target/test_target_lock.cpp | 126 ------------------ .../target/test/target/test_target_source.cpp | 2 + .../test/target/test_toolchain_flag_api.cpp | 45 ------- buildcc/lib/toolchain/CMakeLists.txt | 1 - .../include/toolchain/api/flag_api.h | 1 - .../include/toolchain/common/function_lock.h | 52 -------- .../toolchain/include/toolchain/toolchain.h | 8 +- .../lib/toolchain/src/toolchain/toolchain.cpp | 6 +- 22 files changed, 4 insertions(+), 282 deletions(-) delete mode 100644 buildcc/lib/target/test/target/test_target_lock.cpp delete mode 100644 buildcc/lib/toolchain/include/toolchain/common/function_lock.h diff --git a/buildcc/lib/target/include/target/api/target_getter.h b/buildcc/lib/target/include/target/api/target_getter.h index 3ffdca5e..86b29119 100644 --- a/buildcc/lib/target/include/target/api/target_getter.h +++ b/buildcc/lib/target/include/target/api/target_getter.h @@ -38,7 +38,6 @@ template class TargetGetter { // Target State const TargetState &GetState() const; bool IsBuilt() const; - bool IsLocked() const; // Target Config const TargetConfig &GetConfig() const; diff --git a/buildcc/lib/target/include/target/target_info.h b/buildcc/lib/target/include/target/target_info.h index 4b9f6746..f3bf0549 100644 --- a/buildcc/lib/target/include/target/target_info.h +++ b/buildcc/lib/target/include/target/target_info.h @@ -86,7 +86,6 @@ class TargetInfo : public internal::SourceApi, TargetEnv env_; // - FunctionLock lock_; UserTargetSchema user_; private: diff --git a/buildcc/lib/target/src/api/deps_api.cpp b/buildcc/lib/target/src/api/deps_api.cpp index 18a7c820..98f6094e 100644 --- a/buildcc/lib/target/src/api/deps_api.cpp +++ b/buildcc/lib/target/src/api/deps_api.cpp @@ -24,14 +24,12 @@ template void DepsApi::AddCompileDependencyAbsolute(const fs::path &absolute_path) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.compile_dependencies.insert(absolute_path); } template void DepsApi::AddLinkDependencyAbsolute(const fs::path &absolute_path) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.link_dependencies.insert(absolute_path); } diff --git a/buildcc/lib/target/src/api/flag_api.cpp b/buildcc/lib/target/src/api/flag_api.cpp index a7535250..36b8bab5 100644 --- a/buildcc/lib/target/src/api/flag_api.cpp +++ b/buildcc/lib/target/src/api/flag_api.cpp @@ -24,55 +24,47 @@ template void FlagApi::AddPreprocessorFlag(const std::string &flag) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.preprocessor_flags.insert(flag); } template void FlagApi::AddCommonCompileFlag(const std::string &flag) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.common_compile_flags.insert(flag); } template void FlagApi::AddPchCompileFlag(const std::string &flag) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.pch_compile_flags.insert(flag); } template void FlagApi::AddPchObjectFlag(const std::string &flag) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.pch_object_flags.insert(flag); } template void FlagApi::AddAsmCompileFlag(const std::string &flag) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.asm_compile_flags.insert(flag); } template void FlagApi::AddCCompileFlag(const std::string &flag) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.c_compile_flags.insert(flag); } template void FlagApi::AddCppCompileFlag(const std::string &flag) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.cpp_compile_flags.insert(flag); } template void FlagApi::AddLinkFlag(const std::string &flag) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.link_flags.insert(flag); } diff --git a/buildcc/lib/target/src/api/include_api.cpp b/buildcc/lib/target/src/api/include_api.cpp index 66baa44e..3f4552a1 100644 --- a/buildcc/lib/target/src/api/include_api.cpp +++ b/buildcc/lib/target/src/api/include_api.cpp @@ -24,7 +24,6 @@ template void IncludeApi::AddHeaderAbsolute(const fs::path &absolute_filepath) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); t.user_.headers.insert(absolute_filepath); } @@ -74,7 +73,6 @@ void IncludeApi::AddIncludeDirAbsolute(const fs::path &absolute_include_dir, bool glob_headers) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.include_dirs.insert(absolute_include_dir); if (glob_headers) { diff --git a/buildcc/lib/target/src/api/lib_api.cpp b/buildcc/lib/target/src/api/lib_api.cpp index aa15898a..7a33b333 100644 --- a/buildcc/lib/target/src/api/lib_api.cpp +++ b/buildcc/lib/target/src/api/lib_api.cpp @@ -25,7 +25,6 @@ template void LibApi::AddLibDirAbsolute(const fs::path &absolute_lib_dir) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.lib_dirs.insert(absolute_lib_dir); } @@ -40,14 +39,12 @@ void LibApi::AddLibDir(const fs::path &relative_lib_dir) { template void LibApi::AddLibDep(const BaseTarget &lib_dep) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.libs.push_back(lib_dep.GetTargetPath()); } template void LibApi::AddLibDep(const std::string &lib_dep) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.user_.external_libs.push_back(lib_dep); } diff --git a/buildcc/lib/target/src/api/pch_api.cpp b/buildcc/lib/target/src/api/pch_api.cpp index 35fc16bf..11912bc9 100644 --- a/buildcc/lib/target/src/api/pch_api.cpp +++ b/buildcc/lib/target/src/api/pch_api.cpp @@ -24,7 +24,6 @@ template void PchApi::AddPchAbsolute(const fs::path &absolute_filepath) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); const fs::path absolute_pch = fs::path(absolute_filepath).make_preferred(); diff --git a/buildcc/lib/target/src/api/source_api.cpp b/buildcc/lib/target/src/api/source_api.cpp index 99676c15..8a137384 100644 --- a/buildcc/lib/target/src/api/source_api.cpp +++ b/buildcc/lib/target/src/api/source_api.cpp @@ -24,7 +24,6 @@ template void SourceApi::AddSourceAbsolute(const fs::path &absolute_source) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); t.toolchain_.GetConfig().ExpectsValidSource(absolute_source); t.user_.sources.emplace(fs::path(absolute_source).make_preferred()); } diff --git a/buildcc/lib/target/src/api/sync_api.cpp b/buildcc/lib/target/src/api/sync_api.cpp index e947fb56..6356f83d 100644 --- a/buildcc/lib/target/src/api/sync_api.cpp +++ b/buildcc/lib/target/src/api/sync_api.cpp @@ -41,7 +41,6 @@ template void SyncApi::SpecializedCopy(TargetType target, std::initializer_list options) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); for (const SyncOption o : options) { switch (o) { case SyncOption::PreprocessorFlags: @@ -122,7 +121,6 @@ template void SyncApi::SpecializedInsert(TargetType target, std::initializer_list options) { T &t = static_cast(*this); - t.lock_.ExpectsUnlock(__FUNCTION__); for (const SyncOption o : options) { switch (o) { case SyncOption::PreprocessorFlags: diff --git a/buildcc/lib/target/src/api/target_getter.cpp b/buildcc/lib/target/src/api/target_getter.cpp index 61540bff..42262fdd 100644 --- a/buildcc/lib/target/src/api/target_getter.cpp +++ b/buildcc/lib/target/src/api/target_getter.cpp @@ -40,12 +40,6 @@ template const TargetConfig &TargetGetter::GetConfig() const { return t.config_; } -template bool TargetGetter::IsLocked() const { - const T &t = static_cast(*this); - - return t.lock_.IsLocked(); -} - template const fs::path &TargetGetter::GetBinaryPath() const { const T &t = static_cast(*this); @@ -95,7 +89,6 @@ const std::string & TargetGetter::GetCompileCommand(const fs::path &source) const { const T &t = static_cast(*this); - t.lock_.ExpectsLock(__FUNCTION__); return t.compile_object_.GetObjectData(source).command; } @@ -103,14 +96,12 @@ template const std::string &TargetGetter::GetLinkCommand() const { const T &t = static_cast(*this); - t.lock_.ExpectsLock(__FUNCTION__); return t.link_target_.GetCommand(); } template tf::Taskflow &TargetGetter::GetTaskflow() { T &t = static_cast(*this); - t.lock_.ExpectsLock(__FUNCTION__); return t.tf_; } diff --git a/buildcc/lib/target/src/target/build.cpp b/buildcc/lib/target/src/target/build.cpp index b1155dec..a6996684 100644 --- a/buildcc/lib/target/src/target/build.cpp +++ b/buildcc/lib/target/src/target/build.cpp @@ -54,9 +54,6 @@ namespace buildcc { void Target::Build() { env::log_trace(name_, __FUNCTION__); - lock_.ExpectsUnlock("Target::Build"); - lock_.Lock(); - // PCH state if (!user_.pchs.empty()) { state_.PchDetected(); diff --git a/buildcc/lib/target/src/target_info/target_info.cpp b/buildcc/lib/target/src/target_info/target_info.cpp index 29d94a4d..2fc83cce 100644 --- a/buildcc/lib/target/src/target_info/target_info.cpp +++ b/buildcc/lib/target/src/target_info/target_info.cpp @@ -21,10 +21,6 @@ namespace buildcc { // PRIVATE void TargetInfo::Initialize() { - // TODO, Update this later - // toolchain_.GetLockInfo().ExpectsLock( - // "Toolchain should be locked before usage through `Toolchain::Lock`"); - std::for_each(toolchain_.GetPreprocessorFlags().begin(), toolchain_.GetPreprocessorFlags().end(), [&](const std::string &flag) { AddPreprocessorFlag(flag); }); diff --git a/buildcc/lib/target/test/target/CMakeLists.txt b/buildcc/lib/target/test/target/CMakeLists.txt index 1e7ef314..46a1a03f 100644 --- a/buildcc/lib/target/test/target/CMakeLists.txt +++ b/buildcc/lib/target/test/target/CMakeLists.txt @@ -136,11 +136,6 @@ add_executable(test_target_user_deps ) target_link_libraries(test_target_user_deps PRIVATE target_interface) -add_executable(test_target_lock - test_target_lock.cpp -) -target_link_libraries(test_target_lock PRIVATE target_interface) - add_executable(test_target_sync test_target_sync.cpp ) @@ -162,7 +157,6 @@ add_test(NAME test_target_external_lib COMMAND test_target_external_lib) add_test(NAME test_target_flags COMMAND test_target_flags) add_test(NAME test_target_user_deps COMMAND test_target_user_deps) -add_test(NAME test_target_lock COMMAND test_target_lock) add_test(NAME test_target_sync COMMAND test_target_sync) diff --git a/buildcc/lib/target/test/target/constants.h.in b/buildcc/lib/target/test/target/constants.h.in index 4dbc78de..16c03b9d 100644 --- a/buildcc/lib/target/test/target/constants.h.in +++ b/buildcc/lib/target/test/target/constants.h.in @@ -17,8 +17,6 @@ inline constexpr char const * BUILD_TARGET_FLAG_INTERMEDIATE_DIR = "@CMAKE_CURRE inline constexpr char const * BUILD_TARGET_USER_DEPS_INTERMEDIATE_DIR = "@CMAKE_CURRENT_SOURCE_DIR@/intermediate/target_user_deps"; -inline constexpr char const * BUILD_TARGET_LOCK_INTERMEDIATE_DIR = "@CMAKE_CURRENT_SOURCE_DIR@/intermediate/target_lock"; - inline constexpr char const * BUILD_TARGET_SYNC_INTERMEDIATE_DIR = "@CMAKE_CURRENT_SOURCE_DIR@/intermediate/target_sync"; inline constexpr char const * BUILD_TARGET_FAILURE_STATES_BUILD_DIR = "@CMAKE_CURRENT_SOURCE_DIR@/intermediate/target_failure_states"; diff --git a/buildcc/lib/target/test/target/test_target_lock.cpp b/buildcc/lib/target/test/target/test_target_lock.cpp deleted file mode 100644 index b3b3f5f9..00000000 --- a/buildcc/lib/target/test/target/test_target_lock.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "constants.h" - -#include "expect_command.h" -#include "expect_target.h" - -#include "target/target.h" - -#include "env/env.h" - -// Third Party - -// NOTE, Make sure all these includes are AFTER the system and header includes -#include "CppUTest/CommandLineTestRunner.h" -#include "CppUTest/MemoryLeakDetectorNewMacros.h" -#include "CppUTest/TestHarness.h" -#include "CppUTest/Utest.h" -#include "CppUTestExt/MockSupport.h" - -// clang-format off -TEST_GROUP(TargetTestLock) -{ - void teardown() { - mock().clear(); - } -}; -// clang-format on - -static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", - buildcc::ToolchainExecutables("as", "gcc", "g++", - "ar", "ld")); - -TEST(TargetTestLock, LockState) { - constexpr const char *const NAME = "LockState.exe"; - buildcc::BaseTarget exe(NAME, buildcc::TargetType::Executable, gcc, "data"); - - CHECK_FALSE(exe.IsLocked()); - - buildcc::env::m::CommandExpect_Execute(1, true); - exe.Build(); - buildcc::m::TargetRunner(exe); - - CHECK_TRUE(exe.IsLocked()); - - mock().checkExpectations(); -} - -TEST(TargetTestLock, Lock_Build) { - constexpr const char *const NAME = "Lock_Build.exe"; - buildcc::BaseTarget exe(NAME, buildcc::TargetType::Executable, gcc, "data"); - - buildcc::env::m::CommandExpect_Execute(1, true); - exe.Build(); - buildcc::m::TargetRunner(exe); - - CHECK_THROWS(std::exception, exe.Build()); - - mock().checkExpectations(); -} - -TEST(TargetTestLock, Lock_APIs) { - constexpr const char *const NAME = "Lock_APIs.exe"; - buildcc::BaseTarget exe(NAME, buildcc::TargetType::Executable, gcc, "data"); - - buildcc::env::m::CommandExpect_Execute(1, true); - exe.Build(); - buildcc::m::TargetRunner(exe); - - mock().checkExpectations(); - - // Sources - CHECK_THROWS(std::exception, exe.AddSource("dummy_main.c")); - CHECK_THROWS(std::exception, exe.GlobSources("")); - - // Headers & Dirs - CHECK_THROWS(std::exception, exe.AddHeader("include/include_header.h")); - CHECK_THROWS(std::exception, exe.GlobHeaders("include/")); - CHECK_THROWS(std::exception, exe.AddIncludeDir("include/")); - CHECK_THROWS(std::exception, exe.AddLibDir("include/")); - - // LibDep - CHECK_THROWS(std::exception, exe.AddLibDep("-lpthread")); - CHECK_THROWS(std::exception, exe.AddLibDep(exe)); - - // Flags - CHECK_THROWS(std::exception, exe.AddPreprocessorFlag("-DTESTING=TRUE")); - CHECK_THROWS(std::exception, exe.AddCommonCompileFlag("-Os")); - CHECK_THROWS(std::exception, exe.AddAsmCompileFlag("-march=arm")); - CHECK_THROWS(std::exception, exe.AddCCompileFlag("-std=c11")); - CHECK_THROWS(std::exception, exe.AddCppCompileFlag("-std=c++17")); - CHECK_THROWS(std::exception, exe.AddLinkFlag("-nostd")); - - // Rebuild - CHECK_THROWS(std::exception, exe.AddCompileDependency("dummy_main.c")); - CHECK_THROWS(std::exception, exe.AddLinkDependency("dummy_main.c")); -} - -TEST(TargetTestLock, Unlock_APIs) { - constexpr const char *const NAME = "Unlock_APIs.exe"; - buildcc::BaseTarget exe(NAME, buildcc::TargetType::Executable, gcc, "data"); - - CHECK_THROWS(std::exception, - exe.GetCompileCommand(exe.GetTargetRootDir() / "dummy_main.c")); - CHECK_THROWS(std::exception, exe.GetLinkCommand()); - CHECK_THROWS(std::exception, exe.GetTaskflow()); - - exe.AddSource("dummy_main.c"); - buildcc::env::m::CommandExpect_Execute(1, true); - buildcc::env::m::CommandExpect_Execute(1, true); - exe.Build(); - buildcc::m::TargetRunner(exe); - mock().checkExpectations(); - - exe.GetCompileCommand(exe.GetTargetRootDir() / "dummy_main.c"); - exe.GetLinkCommand(); - exe.GetTaskflow(); -} - -int main(int ac, char **av) { - const fs::path target_source_intermediate_path = - fs::path(BUILD_TARGET_LOCK_INTERMEDIATE_DIR) / gcc.GetName(); - fs::remove_all(target_source_intermediate_path); - - buildcc::Project::Init(BUILD_SCRIPT_SOURCE, - BUILD_TARGET_LOCK_INTERMEDIATE_DIR); - return CommandLineTestRunner::RunAllTests(ac, av); -} diff --git a/buildcc/lib/target/test/target/test_target_source.cpp b/buildcc/lib/target/test/target/test_target_source.cpp index a7b6ba11..8cd2f1f0 100644 --- a/buildcc/lib/target/test/target/test_target_source.cpp +++ b/buildcc/lib/target/test/target/test_target_source.cpp @@ -243,6 +243,8 @@ TEST(TargetTestSourceGroup, Target_CompileCommand_Throws) { // Throws when you call CompileCommand before Build CHECK_THROWS(std::exception, simple.GetCompileCommand(p)); + // Link Command will be empty before Build + STRCMP_EQUAL(simple.GetLinkCommand().c_str(), ""); } } diff --git a/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp index d6308a89..e48becfb 100644 --- a/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp +++ b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp @@ -14,48 +14,6 @@ TEST_GROUP(ToolchainFlagApiTestGroup) }; // clang-format on -TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Lock) { - buildcc::Toolchain toolchain( - buildcc::ToolchainId::Gcc, "gcc", - buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); - toolchain.Lock(); - CHECK_THROWS(std::exception, toolchain.AddPreprocessorFlag("-preprocessor")); - CHECK_THROWS(std::exception, toolchain.AddAsmCompileFlag("-asm")); - CHECK_THROWS(std::exception, toolchain.AddPchCompileFlag("-pchcompile")); - CHECK_THROWS(std::exception, toolchain.AddPchObjectFlag("-pchobject")); - CHECK_THROWS(std::exception, toolchain.AddCommonCompileFlag("-common")); - CHECK_THROWS(std::exception, toolchain.AddCCompileFlag("-c")); - CHECK_THROWS(std::exception, toolchain.AddCppCompileFlag("-cpp")); - CHECK_THROWS(std::exception, toolchain.AddLinkFlag("-link")); -} - -TEST(ToolchainFlagApiTestGroup, BasicToolchainTest_Unlock) { - buildcc::Toolchain toolchain( - buildcc::ToolchainId::Gcc, "gcc", - buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); - toolchain.AddPreprocessorFlag("-preprocessor"); - toolchain.AddAsmCompileFlag("-asm"); - toolchain.AddPchCompileFlag("-pchcompile"); - toolchain.AddPchObjectFlag("-pchobject"); - toolchain.AddCommonCompileFlag("-common"); - toolchain.AddCCompileFlag("-c"); - toolchain.AddCppCompileFlag("-cpp"); - toolchain.AddLinkFlag("-link"); - CHECK_FALSE(toolchain.GetLockInfo().IsLocked()); - - toolchain.Lock(); - CHECK_TRUE(toolchain.GetLockInfo().IsLocked()); - - CHECK_EQUAL(toolchain.GetPreprocessorFlags().size(), 1); - CHECK_EQUAL(toolchain.GetAsmCompileFlags().size(), 1); - CHECK_EQUAL(toolchain.GetPchCompileFlags().size(), 1); - CHECK_EQUAL(toolchain.GetPchObjectFlags().size(), 1); - CHECK_EQUAL(toolchain.GetCommonCompileFlags().size(), 1); - CHECK_EQUAL(toolchain.GetCCompileFlags().size(), 1); - CHECK_EQUAL(toolchain.GetCppCompileFlags().size(), 1); - CHECK_EQUAL(toolchain.GetLinkFlags().size(), 1); -} - TEST(ToolchainFlagApiTestGroup, BasicTargetTest) { buildcc::Toolchain toolchain( buildcc::ToolchainId::Gcc, "gcc", @@ -70,13 +28,10 @@ TEST(ToolchainFlagApiTestGroup, BasicTargetTest) { toolchain.AddCppCompileFlag("-cpp"); toolchain.AddLinkFlag("-link"); - CHECK_FALSE(toolchain.GetLockInfo().IsLocked()); // TODO, Add this in later // * We should lock our toolchain before using it // { CHECK_THROWS(std::exception, (buildcc::TargetInfo(toolchain, ""))); } - toolchain.Lock(); - CHECK_TRUE(toolchain.GetLockInfo().IsLocked()); { buildcc::TargetInfo targetinfo(toolchain, ""); CHECK_EQUAL(targetinfo.GetPreprocessorFlags().size(), 1); diff --git a/buildcc/lib/toolchain/CMakeLists.txt b/buildcc/lib/toolchain/CMakeLists.txt index ce4f6ac0..ff1def9e 100644 --- a/buildcc/lib/toolchain/CMakeLists.txt +++ b/buildcc/lib/toolchain/CMakeLists.txt @@ -3,7 +3,6 @@ set(TOOLCHAIN_SRCS src/common/toolchain_config.cpp include/toolchain/common/toolchain_config.h include/toolchain/common/file_ext.h - include/toolchain/common/function_lock.h # API src/api/toolchain_find.cpp diff --git a/buildcc/lib/toolchain/include/toolchain/api/flag_api.h b/buildcc/lib/toolchain/include/toolchain/api/flag_api.h index 2fb283ba..2d18e1af 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/flag_api.h +++ b/buildcc/lib/toolchain/include/toolchain/api/flag_api.h @@ -24,7 +24,6 @@ namespace buildcc::internal { // Requires // TargetSchema -// FunctionLock template class FlagApi { public: void AddPreprocessorFlag(const std::string &flag); diff --git a/buildcc/lib/toolchain/include/toolchain/common/function_lock.h b/buildcc/lib/toolchain/include/toolchain/common/function_lock.h deleted file mode 100644 index bef3ee34..00000000 --- a/buildcc/lib/toolchain/include/toolchain/common/function_lock.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TARGET_COMMON_FUNCTION_LOCK_H_ -#define TARGET_COMMON_FUNCTION_LOCK_H_ - -#include - -#include "fmt/format.h" - -#include "env/assert_fatal.h" - -namespace buildcc { - -class FunctionLock { -public: - FunctionLock(bool initial_value = false) : lock_(initial_value) {} - - void SetLock(bool lock) { lock_ = lock; } - void Lock() { SetLock(true); } - void Unlock() { SetLock(false); } - - bool IsLocked() const { return lock_; } - - void ExpectsUnlock(std::string_view message) const { - env::assert_fatal(!lock_, - fmt::format("Expects lock == false. {}", message)); - } - void ExpectsLock(std::string_view message) const { - env::assert_fatal(lock_, fmt::format("Expects lock == true. {}", message)); - } - -private: - bool lock_{false}; -}; - -} // namespace buildcc - -#endif diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 55eeb30e..f93867a4 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -22,7 +22,6 @@ #include #include -#include "toolchain/common/function_lock.h" #include "toolchain/common/toolchain_config.h" #include "toolchain/common/toolchain_executables.h" #include "toolchain/common/toolchain_id.h" @@ -42,8 +41,7 @@ class Toolchain : public internal::FlagApi, Toolchain(ToolchainId id, std::string_view name, const ToolchainExecutables &executables, const ToolchainConfig &config = ToolchainConfig()) - : id_(id), name_(name), executables_(executables), config_(config), - lock_(false) {} + : id_(id), name_(name), executables_(executables), config_(config) {} virtual ~Toolchain() = default; Toolchain(Toolchain &&) = default; @@ -51,8 +49,6 @@ class Toolchain : public internal::FlagApi, Toolchain(const Toolchain &) = delete; Toolchain &operator=(const Toolchain &) = delete; - void Lock(); - // Getters ToolchainId GetId() const { return id_; } const std::string &GetName() const { return name_; } @@ -67,7 +63,6 @@ class Toolchain : public internal::FlagApi, return executables_; } - const FunctionLock &GetLockInfo() const { return lock_; } const ToolchainConfig &GetConfig() const { return config_; } protected: @@ -97,7 +92,6 @@ class Toolchain : public internal::FlagApi, std::string name_; ToolchainExecutables executables_; ToolchainConfig config_; - FunctionLock lock_; // UserSchema user_; diff --git a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp index 55889c02..3c5a3141 100644 --- a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp +++ b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp @@ -18,8 +18,4 @@ #include -namespace buildcc { - -void Toolchain::Lock() { lock_.Lock(); } - -} // namespace buildcc +namespace buildcc {} // namespace buildcc From 4d9a71e4a5ad8660df51a11ec300d852ad720714 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 16 Oct 2022 16:09:28 -0700 Subject: [PATCH 25/35] [Cleanup] Builder Interface (#218) --- buildcc/lib/args/include/args/register.h | 9 ++++----- .../lib/target/include/target/api/target_getter.h | 2 -- .../lib/target/include/target/custom_generator.h | 15 ++++++--------- .../include/target/interface/builder_interface.h | 4 ++++ buildcc/lib/target/include/target/target.h | 1 - buildcc/lib/target/src/api/target_getter.cpp | 6 ------ .../src/custom_generator/custom_generator.cpp | 6 ++++++ 7 files changed, 20 insertions(+), 23 deletions(-) diff --git a/buildcc/lib/args/include/args/register.h b/buildcc/lib/args/include/args/register.h index 62013db4..960d708f 100644 --- a/buildcc/lib/args/include/args/register.h +++ b/buildcc/lib/args/include/args/register.h @@ -85,11 +85,10 @@ class Reg::Instance { template void Build(const C &build_cb, T &builder, Params &&...params) { - constexpr bool is_supported_base = std::is_base_of_v || - std::is_base_of_v; - static_assert( - is_supported_base, - "Build only supports BaseTarget, CustomGenerator and derivatives"); + constexpr bool is_supported_base = + std::is_base_of_v; + static_assert(is_supported_base, + "Build only supports Generator, Target and derivatives"); build_cb(builder, std::forward(params)...); tf::Task task = BuildTask(builder); diff --git a/buildcc/lib/target/include/target/api/target_getter.h b/buildcc/lib/target/include/target/api/target_getter.h index 86b29119..7a05a79f 100644 --- a/buildcc/lib/target/include/target/api/target_getter.h +++ b/buildcc/lib/target/include/target/api/target_getter.h @@ -74,8 +74,6 @@ template class TargetGetter { // TODO, Add GetPchCommand if required const std::string &GetCompileCommand(const fs::path &source) const; const std::string &GetLinkCommand() const; - - tf::Taskflow &GetTaskflow(); }; }; // namespace buildcc::internal diff --git a/buildcc/lib/target/include/target/custom_generator.h b/buildcc/lib/target/include/target/custom_generator.h index c6630b9c..327cd914 100644 --- a/buildcc/lib/target/include/target/custom_generator.h +++ b/buildcc/lib/target/include/target/custom_generator.h @@ -22,8 +22,6 @@ #include #include -#include "taskflow/taskflow.hpp" - #include "env/command.h" #include "env/task_state.h" @@ -125,6 +123,11 @@ class CustomGenerator : public internal::BuilderInterface { void AddPatterns(const std::unordered_map &pattern_map); + // TODO, Doc + std::string ParsePattern(const std::string &pattern, + const std::unordered_map + &arguments = {}) const; + /** * @brief Single Generator task for inputs->generate_cb->outputs * @@ -140,6 +143,7 @@ class CustomGenerator : public internal::BuilderInterface { const GenerateCb &generate_cb, std::shared_ptr blob_handler = nullptr); + // TODO, Doc void AddGroup(const std::string &group_id, std::initializer_list ids, const DependencyCb &dependency_cb = DependencyCb()); @@ -170,7 +174,6 @@ class CustomGenerator : public internal::BuilderInterface { } const fs::path &GetRootDir() const { return env_.GetTargetRootDir(); } const fs::path &GetBuildDir() const { return env_.GetTargetBuildDir(); } - tf::Taskflow &GetTaskflow() { return tf_; } const std::string &Get(const std::string &file_identifier) const; private: @@ -193,11 +196,6 @@ class CustomGenerator : public internal::BuilderInterface { void IdUpdated(); protected: - std::string ParsePattern(const std::string &pattern, - const std::unordered_map - &arguments = {}) const { - return command_.Construct(pattern, arguments); - } const env::Command &ConstCommand() const { return command_; } env::Command &RefCommand() { return command_; } @@ -239,7 +237,6 @@ class CustomGenerator : public internal::BuilderInterface { // Internal env::Command command_; - tf::Taskflow tf_; // Callbacks DependencyCb dependency_cb_; diff --git a/buildcc/lib/target/include/target/interface/builder_interface.h b/buildcc/lib/target/include/target/interface/builder_interface.h index cfe40202..90eaa861 100644 --- a/buildcc/lib/target/include/target/interface/builder_interface.h +++ b/buildcc/lib/target/include/target/interface/builder_interface.h @@ -21,6 +21,8 @@ #include #include +#include "taskflow/taskflow.hpp" + #include "env/assert_fatal.h" #include "target/common/util.h" @@ -98,6 +100,7 @@ class BuilderInterface { virtual void Build() = 0; const std::string &GetUniqueId() const { return unique_id_; } + tf::Taskflow &GetTaskflow() { return tf_; } protected: template @@ -154,6 +157,7 @@ class BuilderInterface { protected: bool dirty_{false}; std::string unique_id_; + tf::Taskflow tf_; }; } // namespace buildcc::internal diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index a795bda9..1b764920 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -136,7 +136,6 @@ class Target : public internal::BuilderInterface, // TargetState state_; env::Command command_; - tf::Taskflow tf_; // Task states tf::Task target_start_task_; diff --git a/buildcc/lib/target/src/api/target_getter.cpp b/buildcc/lib/target/src/api/target_getter.cpp index 42262fdd..17494d7f 100644 --- a/buildcc/lib/target/src/api/target_getter.cpp +++ b/buildcc/lib/target/src/api/target_getter.cpp @@ -99,12 +99,6 @@ const std::string &TargetGetter::GetLinkCommand() const { return t.link_target_.GetCommand(); } -template tf::Taskflow &TargetGetter::GetTaskflow() { - T &t = static_cast(*this); - - return t.tf_; -} - template class TargetGetter; } // namespace buildcc::internal diff --git a/buildcc/lib/target/src/custom_generator/custom_generator.cpp b/buildcc/lib/target/src/custom_generator/custom_generator.cpp index 815aba79..7ab3065a 100644 --- a/buildcc/lib/target/src/custom_generator/custom_generator.cpp +++ b/buildcc/lib/target/src/custom_generator/custom_generator.cpp @@ -40,6 +40,12 @@ void CustomGenerator::AddPatterns( } } +std::string CustomGenerator::ParsePattern( + const std::string &pattern, + const std::unordered_map &arguments) const { + return command_.Construct(pattern, arguments); +} + const std::string & CustomGenerator::Get(const std::string &file_identifier) const { return command_.GetDefaultValueByKey(file_identifier); From 4f9dd906c0fbc4aff571a8262761fc4cd8856a6e Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 20 Oct 2022 21:25:18 -0700 Subject: [PATCH 26/35] [Cleanup] CRTP header only (#219) --- .../lib/target/cmake/common_target_src.cmake | 7 -- .../lib/target/include/target/api/deps_api.h | 43 ++++++- .../target/include/target/api/include_api.h | 76 ++++++++++-- .../lib/target/include/target/api/lib_api.h | 48 +++++-- .../lib/target/include/target/api/pch_api.h | 33 ++++- .../target/include/target/api/source_api.h | 53 ++++++-- .../include/target/api/target_info_getter.h | 51 -------- .../target/include/target/common/target_env.h | 19 +++ .../lib/target/include/target/target_info.h | 12 +- buildcc/lib/target/src/api/deps_api.cpp | 54 -------- buildcc/lib/target/src/api/flag_api.cpp | 117 ------------------ buildcc/lib/target/src/api/include_api.cpp | 85 ------------- buildcc/lib/target/src/api/lib_api.cpp | 21 ---- buildcc/lib/target/src/api/pch_api.cpp | 47 ------- buildcc/lib/target/src/api/source_api.cpp | 70 ----------- buildcc/lib/target/src/api/sync_api.cpp | 4 +- buildcc/lib/target/src/api/target_getter.cpp | 36 ++---- .../lib/target/src/api/target_info_getter.cpp | 105 ---------------- .../include/toolchain/api/flag_api.h | 94 +++++++++++--- docs/source/user_api/target.rst | 4 +- 20 files changed, 333 insertions(+), 646 deletions(-) delete mode 100644 buildcc/lib/target/include/target/api/target_info_getter.h delete mode 100644 buildcc/lib/target/src/api/deps_api.cpp delete mode 100644 buildcc/lib/target/src/api/flag_api.cpp delete mode 100644 buildcc/lib/target/src/api/include_api.cpp delete mode 100644 buildcc/lib/target/src/api/pch_api.cpp delete mode 100644 buildcc/lib/target/src/api/source_api.cpp delete mode 100644 buildcc/lib/target/src/api/target_info_getter.cpp diff --git a/buildcc/lib/target/cmake/common_target_src.cmake b/buildcc/lib/target/cmake/common_target_src.cmake index e87f030e..5a10bfe8 100644 --- a/buildcc/lib/target/cmake/common_target_src.cmake +++ b/buildcc/lib/target/cmake/common_target_src.cmake @@ -13,12 +13,7 @@ set(COMMON_TARGET_SRCS include/target/common/util.h # API - src/api/source_api.cpp - src/api/include_api.cpp src/api/lib_api.cpp - src/api/pch_api.cpp - src/api/flag_api.cpp - src/api/deps_api.cpp include/target/api/source_api.h include/target/api/include_api.h include/target/api/lib_api.h @@ -28,9 +23,7 @@ set(COMMON_TARGET_SRCS src/api/sync_api.cpp include/target/api/sync_api.h - src/api/target_info_getter.cpp src/api/target_getter.cpp - include/target/api/target_info_getter.h include/target/api/target_getter.h # Generator diff --git a/buildcc/lib/target/include/target/api/deps_api.h b/buildcc/lib/target/include/target/api/deps_api.h index 0e0c3e61..3fecdf2a 100644 --- a/buildcc/lib/target/include/target/api/deps_api.h +++ b/buildcc/lib/target/include/target/api/deps_api.h @@ -19,42 +19,73 @@ #include +#include "schema/path.h" + namespace fs = std::filesystem; namespace buildcc::internal { // Requires -// - TargetStorer -// - TargetEnv +// User::CompileDependencies +// User::LinkDependencies +// TargetEnv template class DepsApi { public: // TODO, AddPchDependency // TODO, Rename AddObjectDependency // TODO, Rename AddTargetDependency + const fs_unordered_set &GetCompileDependencies() const { + const auto &t = static_cast(*this); + return t.user_.compile_dependencies; + } + + const fs_unordered_set &GetLinkDependencies() const { + const auto &t = static_cast(*this); + return t.user_.link_dependencies; + } + /** * @brief Recompile sources to object if compile dependency is removed, added * or newer from the previous build */ - void AddCompileDependency(const fs::path &relative_path); + void AddCompileDependencyAbsolute(const fs::path &absolute_path) { + auto &t = static_cast(*this); + + t.user_.compile_dependencies.insert(absolute_path); + } /** * @brief Recompile sources to object if compile dependency is removed, added * or newer from the previous build */ - void AddCompileDependencyAbsolute(const fs::path &absolute_path); + void AddCompileDependency(const fs::path &relative_path) { + auto &t = static_cast(*this); + + fs::path absolute_path = t.env_.GetTargetRootDir() / relative_path; + AddCompileDependencyAbsolute(absolute_path); + } /** * @brief Relink target if link dependency is removed, added or newer from * previous build */ - void AddLinkDependency(const fs::path &relative_path); + void AddLinkDependencyAbsolute(const fs::path &absolute_path) { + auto &t = static_cast(*this); + + t.user_.link_dependencies.insert(absolute_path); + } /** * @brief Relink target if link dependency is removed, added or newer from * previous build */ - void AddLinkDependencyAbsolute(const fs::path &absolute_path); + void AddLinkDependency(const fs::path &relative_path) { + auto &t = static_cast(*this); + + fs::path absolute_path = t.env_.GetTargetRootDir() / relative_path; + AddLinkDependencyAbsolute(absolute_path); + } }; } // namespace buildcc::internal diff --git a/buildcc/lib/target/include/target/api/include_api.h b/buildcc/lib/target/include/target/api/include_api.h index 1c98ab54..159594d8 100644 --- a/buildcc/lib/target/include/target/api/include_api.h +++ b/buildcc/lib/target/include/target/api/include_api.h @@ -19,27 +19,83 @@ #include +#include "schema/path.h" + namespace fs = std::filesystem; namespace buildcc::internal { // Requires -// - TargetStorer -// - TargetConfig -// - TargetEnv +// Toolchain +// User::Headers +// User::IncludeDirs +// TargetEnv template class IncludeApi { public: + const fs_unordered_set &GetHeaderFiles() const { + const auto &t = static_cast(*this); + return t.user_.headers; + } + + const fs_unordered_set &GetIncludeDirs() const { + const auto &t = static_cast(*this); + return t.user_.include_dirs; + } + + void AddHeaderAbsolute(const fs::path &absolute_filepath) { + auto &t = static_cast(*this); + + t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); + t.user_.headers.insert(absolute_filepath); + } + + void GlobHeadersAbsolute(const fs::path &absolute_path) { + auto &t = static_cast(*this); + + for (const auto &p : fs::directory_iterator(absolute_path)) { + if (t.toolchain_.GetConfig().IsValidHeader(p.path())) { + AddHeaderAbsolute(p.path()); + } + } + } + + void AddIncludeDirAbsolute(const fs::path &absolute_include_dir, + bool glob_headers = false) { + auto &t = static_cast(*this); + + t.user_.include_dirs.insert(absolute_include_dir); + + if (glob_headers) { + GlobHeadersAbsolute(absolute_include_dir); + } + } + void AddHeader(const fs::path &relative_filename, - const fs::path &relative_to_target_path = ""); - void AddHeaderAbsolute(const fs::path &absolute_filepath); + const fs::path &relative_to_target_path = "") { + auto &t = static_cast(*this); + + // Check Source + fs::path absolute_filepath = + t.env_.GetTargetRootDir() / relative_to_target_path / relative_filename; + AddHeaderAbsolute(absolute_filepath); + } - void GlobHeaders(const fs::path &relative_to_target_path = ""); - void GlobHeadersAbsolute(const fs::path &absolute_path); + void GlobHeaders(const fs::path &relative_to_target_path = "") { + auto &t = static_cast(*this); + + fs::path absolute_path = + t.env_.GetTargetRootDir() / relative_to_target_path; + GlobHeadersAbsolute(absolute_path); + } void AddIncludeDir(const fs::path &relative_include_dir, - bool glob_headers = false); - void AddIncludeDirAbsolute(const fs::path &absolute_include_dir, - bool glob_headers = false); + bool glob_headers = false) { + auto &t = static_cast(*this); + + const fs::path absolute_include_dir = + t.env_.GetTargetRootDir() / relative_include_dir; + AddIncludeDirAbsolute(absolute_include_dir, glob_headers); + } }; } // namespace buildcc::internal diff --git a/buildcc/lib/target/include/target/api/lib_api.h b/buildcc/lib/target/include/target/api/lib_api.h index ecfa44cf..e6fe0bf1 100644 --- a/buildcc/lib/target/include/target/api/lib_api.h +++ b/buildcc/lib/target/include/target/api/lib_api.h @@ -19,6 +19,9 @@ #include #include +#include + +#include "schema/path.h" namespace fs = std::filesystem; @@ -31,16 +34,47 @@ class Target; namespace buildcc::internal { // Requires -// - TargetStorer -// - TargetEnv -// T::GetTargetPath +// User::LibDirs +// User::Libs +// User::ExternalLibs +// TargetEnv +// Target::GetTargetPath template class LibApi { public: - void AddLibDep(const Target &lib_dep); - void AddLibDep(const std::string &lib_dep); + const std::vector &GetLibDeps() const { + const auto &t = static_cast(*this); + return t.user_.libs; + } + + const std::vector &GetExternalLibDeps() const { + const auto &t = static_cast(*this); + return t.user_.external_libs; + } + + const fs_unordered_set &GetLibDirs() const { + const auto &t = static_cast(*this); + return t.user_.lib_dirs; + } - void AddLibDir(const fs::path &relative_lib_dir); - void AddLibDirAbsolute(const fs::path &absolute_lib_dir); + void AddLibDirAbsolute(const fs::path &absolute_lib_dir) { + auto &t = static_cast(*this); + t.user_.lib_dirs.insert(absolute_lib_dir); + } + + void AddLibDir(const fs::path &relative_lib_dir) { + auto &t = static_cast(*this); + fs::path final_lib_dir = t.env_.GetTargetRootDir() / relative_lib_dir; + AddLibDirAbsolute(final_lib_dir); + } + + void AddLibDep(const std::string &lib_dep) { + auto &t = static_cast(*this); + t.user_.external_libs.push_back(lib_dep); + } + + // Target class has been forward declared + // This is because this file is meant to be used by `TargetInfo` and `Target` + void AddLibDep(const Target &lib_dep); }; } // namespace buildcc::internal diff --git a/buildcc/lib/target/include/target/api/pch_api.h b/buildcc/lib/target/include/target/api/pch_api.h index 42c53d7a..7dfdd34e 100644 --- a/buildcc/lib/target/include/target/api/pch_api.h +++ b/buildcc/lib/target/include/target/api/pch_api.h @@ -19,19 +19,42 @@ #include +#include "schema/path.h" + namespace fs = std::filesystem; namespace buildcc::internal { // Requires -// - TargetStorer -// - TargetConfig -// - TargetEnv +// Toolchain +// User::Pchs +// TargetEnv template class PchApi { public: + const fs_unordered_set &GetPchFiles() const { + const auto &t = static_cast(*this); + return t.user_.pchs; + } + + void AddPchAbsolute(const fs::path &absolute_filepath) { + auto &t = static_cast(*this); + + t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); + + const fs::path absolute_pch = fs::path(absolute_filepath).make_preferred(); + t.user_.pchs.insert(absolute_pch); + } + void AddPch(const fs::path &relative_filename, - const fs::path &relative_to_target_path = ""); - void AddPchAbsolute(const fs::path &absolute_filepath); + const fs::path &relative_to_target_path = "") { + auto &t = static_cast(*this); + + // Compute the absolute source path + fs::path absolute_pch = + t.env_.GetTargetRootDir() / relative_to_target_path / relative_filename; + + AddPchAbsolute(absolute_pch); + } }; } // namespace buildcc::internal diff --git a/buildcc/lib/target/include/target/api/source_api.h b/buildcc/lib/target/include/target/api/source_api.h index 35bd6cd2..7ff7eee6 100644 --- a/buildcc/lib/target/include/target/api/source_api.h +++ b/buildcc/lib/target/include/target/api/source_api.h @@ -19,22 +19,61 @@ #include +#include "schema/path.h" + namespace fs = std::filesystem; namespace buildcc::internal { // Requires -// - TargetStorer -// - TargetConfig -// - TargetEnv +// Toolchain +// User::Sources +// TargetEnv template class SourceApi { public: - void AddSourceAbsolute(const fs::path &absolute_source); - void GlobSourcesAbsolute(const fs::path &absolute_source_dir); + const fs_unordered_set &GetSourceFiles() const { + const auto &t = static_cast(*this); + return t.user_.sources; + } + + void AddSourceAbsolute(const fs::path &absolute_source) { + auto &t = static_cast(*this); + + t.toolchain_.GetConfig().ExpectsValidSource(absolute_source); + t.user_.sources.emplace(fs::path(absolute_source).make_preferred()); + } + + void GlobSourcesAbsolute(const fs::path &absolute_source_dir) { + auto &t = static_cast(*this); + + for (const auto &p : fs::directory_iterator(absolute_source_dir)) { + if (t.toolchain_.GetConfig().IsValidSource(p.path())) { + AddSourceAbsolute(p.path()); + } + } + } void AddSource(const fs::path &relative_source, - const fs::path &relative_to_target_path = ""); - void GlobSources(const fs::path &relative_to_target_path = ""); + const fs::path &relative_to_target_path = "") { + auto &t = static_cast(*this); + + // Compute the absolute source path + fs::path absolute_source = + t.env_.GetTargetRootDir() / relative_to_target_path / relative_source; + AddSourceAbsolute(absolute_source); + } + + void GlobSources(const fs::path &relative_to_target_path = "") { + auto &t = static_cast(*this); + + fs::path absolute_input_path = + t.env_.GetTargetRootDir() / relative_to_target_path; + for (const auto &p : fs::directory_iterator(absolute_input_path)) { + if (t.toolchain_.GetConfig().IsValidSource(p.path())) { + AddSourceAbsolute(p.path()); + } + } + } }; } // namespace buildcc::internal diff --git a/buildcc/lib/target/include/target/api/target_info_getter.h b/buildcc/lib/target/include/target/api/target_info_getter.h deleted file mode 100644 index 814a8238..00000000 --- a/buildcc/lib/target/include/target/api/target_info_getter.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TARGET_API_TARGET_INFO_GETTER_H_ -#define TARGET_API_TARGET_INFO_GETTER_H_ - -#include "schema/path.h" - -#include "target/common/target_state.h" - -namespace buildcc::internal { - -// Requires -// - TargetStorer -// - TargetEnv -// - TargetConfig -template class TargetInfoGetter { -public: - // Target Env - const fs::path &GetTargetRootDir() const; - const fs::path &GetTargetBuildDir() const; - - // Target Storer - const fs_unordered_set &GetSourceFiles() const; - const fs_unordered_set &GetHeaderFiles() const; - const fs_unordered_set &GetPchFiles() const; - const std::vector &GetLibDeps() const; - const std::vector &GetExternalLibDeps() const; - const fs_unordered_set &GetIncludeDirs() const; - const fs_unordered_set &GetLibDirs() const; - - const fs_unordered_set &GetCompileDependencies() const; - const fs_unordered_set &GetLinkDependencies() const; -}; - -} // namespace buildcc::internal - -#endif diff --git a/buildcc/lib/target/include/target/common/target_env.h b/buildcc/lib/target/include/target/common/target_env.h index 322d7213..dacdb847 100644 --- a/buildcc/lib/target/include/target/common/target_env.h +++ b/buildcc/lib/target/include/target/common/target_env.h @@ -82,6 +82,25 @@ class TargetEnv { bool relative_{false}; }; +namespace internal { + +// Requires +// TargetEnv +template class TargetEnvApi { +public: + const fs::path &GetTargetRootDir() const { + const auto &t = static_cast(*this); + return t.env_.GetTargetRootDir(); + } + + const fs::path &GetTargetBuildDir() const { + const auto &t = static_cast(*this); + return t.env_.GetTargetBuildDir(); + } +}; + +} // namespace internal + } // namespace buildcc #endif diff --git a/buildcc/lib/target/include/target/target_info.h b/buildcc/lib/target/include/target/target_info.h index f3bf0549..10b1c5c9 100644 --- a/buildcc/lib/target/include/target/target_info.h +++ b/buildcc/lib/target/include/target/target_info.h @@ -21,7 +21,6 @@ #include "toolchain/toolchain.h" -#include "target/common/target_config.h" #include "target/common/target_env.h" #include "target/api/deps_api.h" @@ -30,7 +29,6 @@ #include "target/api/pch_api.h" #include "target/api/source_api.h" #include "target/api/sync_api.h" -#include "target/api/target_info_getter.h" #include "schema/target_serialization.h" @@ -59,7 +57,7 @@ class TargetInfo : public internal::SourceApi, public internal::FlagApi, public internal::DepsApi, public internal::SyncApi, - public internal::TargetInfoGetter { + public internal::TargetEnvApi { public: TargetInfo(const BaseToolchain &toolchain, const TargetEnv &env) : toolchain_(toolchain), env_(env) { @@ -67,25 +65,19 @@ class TargetInfo : public internal::SourceApi, } private: - // Inputs friend class internal::SourceApi; friend class internal::IncludeApi; friend class internal::LibApi; friend class internal::PchApi; friend class internal::FlagApi; friend class internal::DepsApi; - - // Feature friend class internal::SyncApi; - - // Getters - friend class internal::TargetInfoGetter; + friend class internal::TargetEnvApi; protected: const BaseToolchain &toolchain_; TargetEnv env_; - // UserTargetSchema user_; private: diff --git a/buildcc/lib/target/src/api/deps_api.cpp b/buildcc/lib/target/src/api/deps_api.cpp deleted file mode 100644 index 98f6094e..00000000 --- a/buildcc/lib/target/src/api/deps_api.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/api/deps_api.h" - -#include "target/target_info.h" - -namespace buildcc::internal { - -template -void DepsApi::AddCompileDependencyAbsolute(const fs::path &absolute_path) { - T &t = static_cast(*this); - - t.user_.compile_dependencies.insert(absolute_path); -} -template -void DepsApi::AddLinkDependencyAbsolute(const fs::path &absolute_path) { - T &t = static_cast(*this); - - t.user_.link_dependencies.insert(absolute_path); -} - -template -void DepsApi::AddCompileDependency(const fs::path &relative_path) { - T &t = static_cast(*this); - - fs::path absolute_path = t.env_.GetTargetRootDir() / relative_path; - AddCompileDependencyAbsolute(absolute_path); -} - -template -void DepsApi::AddLinkDependency(const fs::path &relative_path) { - T &t = static_cast(*this); - - fs::path absolute_path = t.env_.GetTargetRootDir() / relative_path; - AddLinkDependencyAbsolute(absolute_path); -} - -template class DepsApi; - -} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/api/flag_api.cpp b/buildcc/lib/target/src/api/flag_api.cpp deleted file mode 100644 index 36b8bab5..00000000 --- a/buildcc/lib/target/src/api/flag_api.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "toolchain/api/flag_api.h" - -#include "target/target_info.h" - -namespace buildcc::internal { - -template -void FlagApi::AddPreprocessorFlag(const std::string &flag) { - T &t = static_cast(*this); - - t.user_.preprocessor_flags.insert(flag); -} -template -void FlagApi::AddCommonCompileFlag(const std::string &flag) { - T &t = static_cast(*this); - - t.user_.common_compile_flags.insert(flag); -} -template -void FlagApi::AddPchCompileFlag(const std::string &flag) { - T &t = static_cast(*this); - - t.user_.pch_compile_flags.insert(flag); -} -template -void FlagApi::AddPchObjectFlag(const std::string &flag) { - T &t = static_cast(*this); - - t.user_.pch_object_flags.insert(flag); -} -template -void FlagApi::AddAsmCompileFlag(const std::string &flag) { - T &t = static_cast(*this); - - t.user_.asm_compile_flags.insert(flag); -} -template -void FlagApi::AddCCompileFlag(const std::string &flag) { - T &t = static_cast(*this); - - t.user_.c_compile_flags.insert(flag); -} -template -void FlagApi::AddCppCompileFlag(const std::string &flag) { - T &t = static_cast(*this); - - t.user_.cpp_compile_flags.insert(flag); -} -template void FlagApi::AddLinkFlag(const std::string &flag) { - T &t = static_cast(*this); - - t.user_.link_flags.insert(flag); -} - -template -const std::unordered_set & -FlagApi::GetPreprocessorFlags() const { - const T &t = static_cast(*this); - return t.user_.preprocessor_flags; -} -template -const std::unordered_set & -FlagApi::GetCommonCompileFlags() const { - const T &t = static_cast(*this); - return t.user_.common_compile_flags; -} -template -const std::unordered_set &FlagApi::GetPchCompileFlags() const { - const T &t = static_cast(*this); - return t.user_.pch_compile_flags; -} -template -const std::unordered_set &FlagApi::GetPchObjectFlags() const { - const T &t = static_cast(*this); - return t.user_.pch_object_flags; -} -template -const std::unordered_set &FlagApi::GetAsmCompileFlags() const { - const T &t = static_cast(*this); - return t.user_.asm_compile_flags; -} -template -const std::unordered_set &FlagApi::GetCCompileFlags() const { - const T &t = static_cast(*this); - return t.user_.c_compile_flags; -} -template -const std::unordered_set &FlagApi::GetCppCompileFlags() const { - const T &t = static_cast(*this); - return t.user_.cpp_compile_flags; -} -template -const std::unordered_set &FlagApi::GetLinkFlags() const { - const T &t = static_cast(*this); - return t.user_.link_flags; -} - -template class FlagApi; -template class FlagApi; - -} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/api/include_api.cpp b/buildcc/lib/target/src/api/include_api.cpp deleted file mode 100644 index 3f4552a1..00000000 --- a/buildcc/lib/target/src/api/include_api.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/api/include_api.h" - -#include "target/target_info.h" - -namespace buildcc::internal { - -template -void IncludeApi::AddHeaderAbsolute(const fs::path &absolute_filepath) { - T &t = static_cast(*this); - - t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); - t.user_.headers.insert(absolute_filepath); -} - -template -void IncludeApi::AddHeader(const fs::path &relative_filename, - const fs::path &relative_to_target_path) { - T &t = static_cast(*this); - - // Check Source - fs::path absolute_filepath = - t.env_.GetTargetRootDir() / relative_to_target_path / relative_filename; - AddHeaderAbsolute(absolute_filepath); -} - -template -void IncludeApi::GlobHeaders(const fs::path &relative_to_target_path) { - T &t = static_cast(*this); - - fs::path absolute_path = t.env_.GetTargetRootDir() / relative_to_target_path; - GlobHeadersAbsolute(absolute_path); -} - -template -void IncludeApi::GlobHeadersAbsolute(const fs::path &absolute_path) { - T &t = static_cast(*this); - - for (const auto &p : fs::directory_iterator(absolute_path)) { - if (t.toolchain_.GetConfig().IsValidHeader(p.path())) { - AddHeaderAbsolute(p.path()); - } - } -} - -template -void IncludeApi::AddIncludeDir(const fs::path &relative_include_dir, - bool glob_headers) { - T &t = static_cast(*this); - - const fs::path absolute_include_dir = - t.env_.GetTargetRootDir() / relative_include_dir; - AddIncludeDirAbsolute(absolute_include_dir, glob_headers); -} - -template -void IncludeApi::AddIncludeDirAbsolute(const fs::path &absolute_include_dir, - bool glob_headers) { - T &t = static_cast(*this); - - t.user_.include_dirs.insert(absolute_include_dir); - - if (glob_headers) { - GlobHeadersAbsolute(absolute_include_dir); - } -} - -template class IncludeApi; - -} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/api/lib_api.cpp b/buildcc/lib/target/src/api/lib_api.cpp index 7a33b333..156e3dd8 100644 --- a/buildcc/lib/target/src/api/lib_api.cpp +++ b/buildcc/lib/target/src/api/lib_api.cpp @@ -21,33 +21,12 @@ namespace buildcc::internal { -template -void LibApi::AddLibDirAbsolute(const fs::path &absolute_lib_dir) { - T &t = static_cast(*this); - - t.user_.lib_dirs.insert(absolute_lib_dir); -} - -template -void LibApi::AddLibDir(const fs::path &relative_lib_dir) { - T &t = static_cast(*this); - - fs::path final_lib_dir = t.env_.GetTargetRootDir() / relative_lib_dir; - AddLibDirAbsolute(final_lib_dir); -} - template void LibApi::AddLibDep(const BaseTarget &lib_dep) { T &t = static_cast(*this); t.user_.libs.push_back(lib_dep.GetTargetPath()); } -template void LibApi::AddLibDep(const std::string &lib_dep) { - T &t = static_cast(*this); - - t.user_.external_libs.push_back(lib_dep); -} - template class LibApi; } // namespace buildcc::internal diff --git a/buildcc/lib/target/src/api/pch_api.cpp b/buildcc/lib/target/src/api/pch_api.cpp deleted file mode 100644 index 11912bc9..00000000 --- a/buildcc/lib/target/src/api/pch_api.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/api/pch_api.h" - -#include "target/target_info.h" - -namespace buildcc::internal { - -template -void PchApi::AddPchAbsolute(const fs::path &absolute_filepath) { - T &t = static_cast(*this); - - t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); - - const fs::path absolute_pch = fs::path(absolute_filepath).make_preferred(); - t.user_.pchs.insert(absolute_pch); -} - -template -void PchApi::AddPch(const fs::path &relative_filename, - const fs::path &relative_to_target_path) { - T &t = static_cast(*this); - - // Compute the absolute source path - fs::path absolute_pch = - t.env_.GetTargetRootDir() / relative_to_target_path / relative_filename; - - AddPchAbsolute(absolute_pch); -} - -template class PchApi; - -} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/api/source_api.cpp b/buildcc/lib/target/src/api/source_api.cpp deleted file mode 100644 index 8a137384..00000000 --- a/buildcc/lib/target/src/api/source_api.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/api/source_api.h" - -#include "target/target_info.h" - -namespace buildcc::internal { - -template -void SourceApi::AddSourceAbsolute(const fs::path &absolute_source) { - T &t = static_cast(*this); - - t.toolchain_.GetConfig().ExpectsValidSource(absolute_source); - t.user_.sources.emplace(fs::path(absolute_source).make_preferred()); -} - -template -void SourceApi::GlobSourcesAbsolute(const fs::path &absolute_source_dir) { - T &t = static_cast(*this); - - for (const auto &p : fs::directory_iterator(absolute_source_dir)) { - if (t.toolchain_.GetConfig().IsValidSource(p.path())) { - AddSourceAbsolute(p.path()); - } - } -} - -template -void SourceApi::AddSource( - const fs::path &relative_source, - const std::filesystem::path &relative_to_target_path) { - T &t = static_cast(*this); - - // Compute the absolute source path - fs::path absolute_source = - t.env_.GetTargetRootDir() / relative_to_target_path / relative_source; - AddSourceAbsolute(absolute_source); -} - -template -void SourceApi::GlobSources(const fs::path &relative_to_target_path) { - T &t = static_cast(*this); - - fs::path absolute_input_path = - t.env_.GetTargetRootDir() / relative_to_target_path; - for (const auto &p : fs::directory_iterator(absolute_input_path)) { - if (t.toolchain_.GetConfig().IsValidSource(p.path())) { - AddSourceAbsolute(p.path()); - } - } -} - -// -template class SourceApi; - -} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/api/sync_api.cpp b/buildcc/lib/target/src/api/sync_api.cpp index 6356f83d..c10073f4 100644 --- a/buildcc/lib/target/src/api/sync_api.cpp +++ b/buildcc/lib/target/src/api/sync_api.cpp @@ -40,7 +40,7 @@ template template void SyncApi::SpecializedCopy(TargetType target, std::initializer_list options) { - T &t = static_cast(*this); + auto &t = static_cast(*this); for (const SyncOption o : options) { switch (o) { case SyncOption::PreprocessorFlags: @@ -120,7 +120,7 @@ template template void SyncApi::SpecializedInsert(TargetType target, std::initializer_list options) { - T &t = static_cast(*this); + auto &t = static_cast(*this); for (const SyncOption o : options) { switch (o) { case SyncOption::PreprocessorFlags: diff --git a/buildcc/lib/target/src/api/target_getter.cpp b/buildcc/lib/target/src/api/target_getter.cpp index 17494d7f..dc25a826 100644 --- a/buildcc/lib/target/src/api/target_getter.cpp +++ b/buildcc/lib/target/src/api/target_getter.cpp @@ -22,80 +22,68 @@ namespace buildcc::internal { // Target State template const TargetState &TargetGetter::GetState() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.state_; } template bool TargetGetter::IsBuilt() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.state_.IsBuilt(); } // Target Config template const TargetConfig &TargetGetter::GetConfig() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.config_; } template const fs::path &TargetGetter::GetBinaryPath() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.serialization_.GetSerializedFile(); } template const fs::path &TargetGetter::GetTargetPath() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.link_target_.GetOutput(); } template const fs::path &TargetGetter::GetPchHeaderPath() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.compile_pch_.GetHeaderPath(); } template const fs::path &TargetGetter::GetPchCompilePath() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.compile_pch_.GetCompilePath(); } template const std::string &TargetGetter::GetName() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.name_; } template const Toolchain &TargetGetter::GetToolchain() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.toolchain_; } template TargetType TargetGetter::GetType() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.type_; } template const std::string & TargetGetter::GetCompileCommand(const fs::path &source) const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.compile_object_.GetObjectData(source).command; } template const std::string &TargetGetter::GetLinkCommand() const { - const T &t = static_cast(*this); - + const auto &t = static_cast(*this); return t.link_target_.GetCommand(); } diff --git a/buildcc/lib/target/src/api/target_info_getter.cpp b/buildcc/lib/target/src/api/target_info_getter.cpp deleted file mode 100644 index 7083fa48..00000000 --- a/buildcc/lib/target/src/api/target_info_getter.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/api/target_info_getter.h" - -#include "target/target_info.h" - -namespace buildcc::internal { - -// Target Env -template -const fs::path &TargetInfoGetter::GetTargetRootDir() const { - const T &t = static_cast(*this); - - return t.env_.GetTargetRootDir(); -} - -template -const fs::path &TargetInfoGetter::GetTargetBuildDir() const { - const T &t = static_cast(*this); - - return t.env_.GetTargetBuildDir(); -} - -// Target Storer -template -const fs_unordered_set &TargetInfoGetter::GetSourceFiles() const { - const T &t = static_cast(*this); - - return t.user_.sources; -} - -template -const fs_unordered_set &TargetInfoGetter::GetHeaderFiles() const { - const T &t = static_cast(*this); - - return t.user_.headers; -} - -template -const fs_unordered_set &TargetInfoGetter::GetPchFiles() const { - const T &t = static_cast(*this); - - return t.user_.pchs; -} - -template -const std::vector &TargetInfoGetter::GetLibDeps() const { - const T &t = static_cast(*this); - - return t.user_.libs; -} - -template -const std::vector & -TargetInfoGetter::GetExternalLibDeps() const { - const T &t = static_cast(*this); - - return t.user_.external_libs; -} - -template -const fs_unordered_set &TargetInfoGetter::GetIncludeDirs() const { - const T &t = static_cast(*this); - - return t.user_.include_dirs; -} - -template -const fs_unordered_set &TargetInfoGetter::GetLibDirs() const { - const T &t = static_cast(*this); - - return t.user_.lib_dirs; -} - -template -const fs_unordered_set &TargetInfoGetter::GetCompileDependencies() const { - const T &t = static_cast(*this); - - return t.user_.compile_dependencies; -} - -template -const fs_unordered_set &TargetInfoGetter::GetLinkDependencies() const { - const T &t = static_cast(*this); - - return t.user_.link_dependencies; -} - -template class TargetInfoGetter; - -} // namespace buildcc::internal diff --git a/buildcc/lib/toolchain/include/toolchain/api/flag_api.h b/buildcc/lib/toolchain/include/toolchain/api/flag_api.h index 2d18e1af..5953d243 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/flag_api.h +++ b/buildcc/lib/toolchain/include/toolchain/api/flag_api.h @@ -26,24 +26,86 @@ namespace buildcc::internal { // TargetSchema template class FlagApi { public: - void AddPreprocessorFlag(const std::string &flag); - void AddCommonCompileFlag(const std::string &flag); - void AddPchCompileFlag(const std::string &flag); - void AddPchObjectFlag(const std::string &flag); - void AddAsmCompileFlag(const std::string &flag); - void AddCCompileFlag(const std::string &flag); - void AddCppCompileFlag(const std::string &flag); - void AddLinkFlag(const std::string &flag); + void AddPreprocessorFlag(const std::string &flag) { + auto &t = static_cast(*this); + t.user_.preprocessor_flags.insert(flag); + } + + void AddCommonCompileFlag(const std::string &flag) { + auto &t = static_cast(*this); + t.user_.common_compile_flags.insert(flag); + } + + void AddPchCompileFlag(const std::string &flag) { + auto &t = static_cast(*this); + t.user_.pch_compile_flags.insert(flag); + } + + void AddPchObjectFlag(const std::string &flag) { + auto &t = static_cast(*this); + t.user_.pch_object_flags.insert(flag); + } + + void AddAsmCompileFlag(const std::string &flag) { + auto &t = static_cast(*this); + t.user_.asm_compile_flags.insert(flag); + } + + void AddCCompileFlag(const std::string &flag) { + auto &t = static_cast(*this); + t.user_.c_compile_flags.insert(flag); + } + + void AddCppCompileFlag(const std::string &flag) { + auto &t = static_cast(*this); + t.user_.cpp_compile_flags.insert(flag); + } + + void AddLinkFlag(const std::string &flag) { + auto &t = static_cast(*this); + t.user_.link_flags.insert(flag); + } // Getters - const std::unordered_set &GetPreprocessorFlags() const; - const std::unordered_set &GetCommonCompileFlags() const; - const std::unordered_set &GetPchCompileFlags() const; - const std::unordered_set &GetPchObjectFlags() const; - const std::unordered_set &GetAsmCompileFlags() const; - const std::unordered_set &GetCCompileFlags() const; - const std::unordered_set &GetCppCompileFlags() const; - const std::unordered_set &GetLinkFlags() const; + const std::unordered_set &GetPreprocessorFlags() const { + const auto &t = static_cast(*this); + return t.user_.preprocessor_flags; + } + + const std::unordered_set &GetCommonCompileFlags() const { + const auto &t = static_cast(*this); + return t.user_.common_compile_flags; + } + + const std::unordered_set &GetPchCompileFlags() const { + const auto &t = static_cast(*this); + return t.user_.pch_compile_flags; + } + + const std::unordered_set &GetPchObjectFlags() const { + const auto &t = static_cast(*this); + return t.user_.pch_object_flags; + } + + const std::unordered_set &GetAsmCompileFlags() const { + const auto &t = static_cast(*this); + return t.user_.asm_compile_flags; + } + + const std::unordered_set &GetCCompileFlags() const { + const auto &t = static_cast(*this); + return t.user_.c_compile_flags; + } + + const std::unordered_set &GetCppCompileFlags() const { + const auto &t = static_cast(*this); + return t.user_.cpp_compile_flags; + } + + const std::unordered_set &GetLinkFlags() const { + const auto &t = static_cast(*this); + return t.user_.link_flags; + } }; } // namespace buildcc::internal diff --git a/docs/source/user_api/target.rst b/docs/source/user_api/target.rst index 30931368..5d3d7aa7 100644 --- a/docs/source/user_api/target.rst +++ b/docs/source/user_api/target.rst @@ -56,10 +56,10 @@ Target APIs .. important:: Target APIs can also use TargetInfo APIs -target_info_getter.h +target_env.h --------------------- -.. doxygenclass:: buildcc::internal::TargetGetter +.. doxygenclass:: buildcc::internal::TargetEnvApi Target ======= From 5df63112dfc6a43b1c9ac29848369ce3e064161f Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 26 Oct 2022 02:42:33 -0700 Subject: [PATCH 27/35] [Utility] Added tl::optional library (#221) --- .gitmodules | 3 ++ CMakeLists.txt | 1 + DEPENDENCIES.md | 11 +++++++ README.md | 2 ++ bootstrap/CMakeLists.txt | 1 + bootstrap/include/bootstrap/build_buildcc.h | 8 ++++- .../include/bootstrap/build_tl_optional.h | 28 ++++++++++++++++++ bootstrap/main.buildcc.cpp | 1 + bootstrap/src/build_buildcc.cpp | 17 +++++++++-- bootstrap/src/build_tl_optional.cpp | 26 ++++++++++++++++ buildcc/CMakeLists.txt | 1 + buildcc/lib/args/include/args/register.h | 4 +-- .../args/include/args/register/test_info.h | 17 +++++++---- buildcc/lib/args/src/tasks.cpp | 1 + buildcc/lib/env/CMakeLists.txt | 8 ++++- buildcc/lib/env/include/env/command.h | 5 ++-- buildcc/lib/env/include/env/optional.h | 28 ++++++++++++++++++ buildcc/lib/env/mock/execute.cpp | 2 +- buildcc/lib/env/src/execute.cpp | 6 ++-- buildcc/lib/target/include/target/target.h | 5 ++-- buildcc/lib/target/src/target/target.cpp | 4 +-- .../include/toolchain/api/toolchain_verify.h | 8 ++--- .../toolchain/include/toolchain/toolchain.h | 1 - .../toolchain/src/api/toolchain_verify.cpp | 13 ++++++-- .../toolchain/test/test_toolchain_verify.cpp | 2 +- .../targets/include/targets/target_generic.h | 9 +++--- .../include/toolchains/toolchain_custom.h | 2 +- .../include/toolchains/toolchain_gcc.h | 4 +-- .../include/toolchains/toolchain_generic.h | 4 +-- .../include/toolchains/toolchain_mingw.h | 7 +++-- .../include/toolchains/toolchain_msvc.h | 4 +-- .../toolchains/src/toolchain_aggregate.cpp | 10 +++---- buildcc/toolchains/src/toolchain_infos.cpp | 14 ++++----- .../test/test_toolchain_specialized.cpp | 4 +-- buildexe/CMakeLists.txt | 1 + cmake/target/tl_optional.cmake | 2 ++ .../buildcc_interface_lib.PNG | Bin 151647 -> 156596 bytes .../buildcc_single_lib.PNG | Bin 120571 -> 128739 bytes docs/source/user_api/toolchain.rst | 2 +- example/gcc/AfterInstall/CMakeLists.txt | 2 ++ third_party/tl_optional | 1 + 41 files changed, 207 insertions(+), 62 deletions(-) create mode 100644 bootstrap/include/bootstrap/build_tl_optional.h create mode 100644 bootstrap/src/build_tl_optional.cpp create mode 100644 buildcc/lib/env/include/env/optional.h create mode 100644 cmake/target/tl_optional.cmake create mode 160000 third_party/tl_optional diff --git a/.gitmodules b/.gitmodules index 7deee242..6c29f7ec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "tiny-process-library"] path = third_party/tiny-process-library url = https://gitlab.com/eidheim/tiny-process-library.git +[submodule "optional"] + path = third_party/tl_optional + url = https://github.com/TartanLlama/optional.git diff --git a/CMakeLists.txt b/CMakeLists.txt index fa0f8d19..76d263e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,7 @@ include(cmake/target/spdlog.cmake) include(cmake/target/cli11.cmake) include(cmake/target/taskflow.cmake) include(cmake/target/tpl.cmake) +include(cmake/target/tl_optional.cmake) if (${TESTING}) include(cmake/target/cpputest.cmake) diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 224bf0ab..fe9d47bc 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -1,5 +1,9 @@ # Dependencies +These third party libraries are added as submodules since they aren't meant to be modified by this project. + +`git submodule add [git_url] third_party/[foldername]` + ## Main - fmt (Formatting) @@ -12,6 +16,13 @@ - cpputest (Unit Testing / Mocking) +## Utility + +- tl_optional (Better optional support) + - Synced with branch origin/master (May 2, 2021) + - Commit Id: c28fcf74d207fc667c4ed3dbae4c251ea551c8c1 + - Needed fix: #45 + ## Tools - [x] clangformat (auto) diff --git a/README.md b/README.md index 038af93f..8feeb09b 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Build C, C++ and ASM files in C++ - fmt v8.0.1 - spdlog v1.9.2 - CppUTest v4.0 + - Tl::Optional (master) # General Information @@ -178,3 +179,4 @@ _BuildCC_ is licensed under the Apache License, Version 2.0. See [LICENSE](LICEN - [Flatbuffers](https://github.com/google/flatbuffers) (Serialization) [Apache-2.0 License] - [CLI11](https://github.com/CLIUtils/CLI11) (Argument Parsing) [BSD-3-Clause License] [Header Only] - [CppUTest](https://github.com/cpputest/cpputest) (Unit Testing/Mocking) [BSD-3-Clause License] +- [Tl::Optional](https://github.com/TartanLlama/optional) (Optional support) [CC0-1.0 License] diff --git a/bootstrap/CMakeLists.txt b/bootstrap/CMakeLists.txt index 4878df29..f07f53d9 100644 --- a/bootstrap/CMakeLists.txt +++ b/bootstrap/CMakeLists.txt @@ -8,6 +8,7 @@ target_sources(buildcc_lib_bootstrap PRIVATE src/build_spdlog.cpp src/build_taskflow.cpp src/build_tpl.cpp + src/build_tl_optional.cpp src/build_buildcc.cpp ) diff --git a/bootstrap/include/bootstrap/build_buildcc.h b/bootstrap/include/bootstrap/build_buildcc.h index e8c55804..a4026f7a 100644 --- a/bootstrap/include/bootstrap/build_buildcc.h +++ b/bootstrap/include/bootstrap/build_buildcc.h @@ -24,6 +24,7 @@ #include "build_fmtlib.h" #include "build_spdlog.h" #include "build_taskflow.h" +#include "build_tl_optional.h" #include "build_tpl.h" namespace buildcc { @@ -33,7 +34,8 @@ void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe); void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, const TargetInfo &flatbuffers_ho, const TargetInfo &fmt_ho, const TargetInfo &spdlog_ho, const TargetInfo &cli11_ho, - const TargetInfo &taskflow_ho, const BaseTarget &tpl); + const TargetInfo &taskflow_ho, const TargetInfo &tl_optional_ho, + const BaseTarget &tpl); /** * @brief @@ -47,6 +49,7 @@ class BuildBuildCC { static constexpr const char *const kFmtHoName = "fmtlib_ho"; static constexpr const char *const kSpdlogHoName = "spdlog_ho"; static constexpr const char *const kTaskflowHoName = "taskflow_ho"; + static constexpr const char *const kTlOptionalHoName = "tl_optional_ho"; // Executable static constexpr const char *const kFlatcExeName = "flatc"; @@ -92,6 +95,9 @@ class BuildBuildCC { TargetInfo &GetTaskflowHo() { return storage_.Ref(kTaskflowHoName); } + TargetInfo &GetTlOptionalHo() { + return storage_.Ref(kTlOptionalHoName); + } private: const BaseToolchain &toolchain_; diff --git a/bootstrap/include/bootstrap/build_tl_optional.h b/bootstrap/include/bootstrap/build_tl_optional.h new file mode 100644 index 00000000..4ca39e01 --- /dev/null +++ b/bootstrap/include/bootstrap/build_tl_optional.h @@ -0,0 +1,28 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BOOTSTRAP_BUILD_TL_OPTIONAL_H_ +#define BOOTSTRAP_BUILD_TL_OPTIONAL_H_ + +#include "buildcc.h" + +namespace buildcc { + +void tl_optional_ho_cb(TargetInfo &info); + +} // namespace buildcc + +#endif diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index 4e8738fd..aac2276f 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -21,6 +21,7 @@ #include "bootstrap/build_fmtlib.h" #include "bootstrap/build_spdlog.h" #include "bootstrap/build_taskflow.h" +#include "bootstrap/build_tl_optional.h" #include "bootstrap/build_tpl.h" #include "bootstrap/build_buildcc.h" diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index 8a0806fe..1e70b401 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -46,7 +46,8 @@ void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe) { void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, const TargetInfo &flatbuffers_ho, const TargetInfo &fmt_ho, const TargetInfo &spdlog_ho, const TargetInfo &cli11_ho, - const TargetInfo &taskflow_ho, const BaseTarget &tpl) { + const TargetInfo &taskflow_ho, const TargetInfo &tl_optional_ho, + const BaseTarget &tpl) { // NOTE, Build as single lib target.AddIncludeDir("", true); const std::string &schema_build_dir = schema_gen.Get("current_build_dir"); @@ -130,6 +131,9 @@ void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, // TASKFLOW HO target.Insert(taskflow_ho, kInsertOptions); + // TL OPTIONAL HO + target.Insert(tl_optional_ho, kInsertOptions); + // TPL LIB target.AddLibDep(tpl); target.Insert(tpl, kInsertOptions); @@ -237,6 +241,12 @@ void BuildBuildCC::Initialize() { TargetEnv(env_.GetTargetRootDir() / "third_party" / "taskflow", env_.GetTargetBuildDir())); + // tl optional HO lib + (void)storage_.Add( + kTlOptionalHoName, toolchain_, + TargetEnv(env_.GetTargetRootDir() / "third_party" / "tl_optional", + env_.GetTargetBuildDir())); + // Tiny-process-library lib // TODO, Make this a generic selection between StaticTarget and // DynamicTarget @@ -262,6 +272,7 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { auto &fmt_ho_lib = GetFmtHo(); auto &spdlog_ho_lib = GetSpdlogHo(); auto &taskflow_ho_lib = GetTaskflowHo(); + auto &tl_optional_ho_lib = GetTlOptionalHo(); auto &tpl_lib = GetTpl(); auto &buildcc_lib = GetBuildcc(); Reg::Toolchain(state) @@ -274,11 +285,13 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { .Func(fmt_ho_cb, fmt_ho_lib) .Func(spdlog_ho_cb, spdlog_ho_lib) .Func(taskflow_ho_cb, taskflow_ho_lib) + .Func(tl_optional_ho_cb, tl_optional_ho_lib) .Func(global_flags_cb, tpl_lib, toolchain_) .Build(tpl_cb, tpl_lib) .Func(global_flags_cb, buildcc_lib, toolchain_) .Build(buildcc_cb, buildcc_lib, schema_gen, flatbuffers_ho_lib, - fmt_ho_lib, spdlog_ho_lib, cli11_ho_lib, taskflow_ho_lib, tpl_lib) + fmt_ho_lib, spdlog_ho_lib, cli11_ho_lib, taskflow_ho_lib, + tl_optional_ho_lib, tpl_lib) .Dep(buildcc_lib, schema_gen) .Dep(buildcc_lib, tpl_lib); } diff --git a/bootstrap/src/build_tl_optional.cpp b/bootstrap/src/build_tl_optional.cpp new file mode 100644 index 00000000..3ac8926c --- /dev/null +++ b/bootstrap/src/build_tl_optional.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bootstrap/build_tl_optional.h" + +namespace buildcc { + +void tl_optional_ho_cb(TargetInfo &info) { + info.AddIncludeDir("include"); + info.GlobHeaders("include/tl"); +} + +} // namespace buildcc diff --git a/buildcc/CMakeLists.txt b/buildcc/CMakeLists.txt index 035da54b..a034aaef 100644 --- a/buildcc/CMakeLists.txt +++ b/buildcc/CMakeLists.txt @@ -12,6 +12,7 @@ if(${BUILDCC_BUILD_AS_SINGLE_LIB}) ) target_link_libraries(buildcc PUBLIC fmt::fmt + tl::optional flatbuffers Taskflow CLI11::CLI11 diff --git a/buildcc/lib/args/include/args/register.h b/buildcc/lib/args/include/args/register.h index 960d708f..76bfa311 100644 --- a/buildcc/lib/args/include/args/register.h +++ b/buildcc/lib/args/include/args/register.h @@ -21,13 +21,12 @@ #include #include "args.h" +#include "args/register/test_info.h" #include "target/custom_generator.h" #include "target/file_generator.h" #include "target/target.h" -#include "args/register/test_info.h" - #include "taskflow/taskflow.hpp" namespace buildcc { @@ -134,7 +133,6 @@ class Reg::Instance { // Getters const tf::Taskflow &GetTaskflow() const { return build_tf_; } -private: private: // BuildTasks tf::Task BuildTask(BaseTarget &target); diff --git a/buildcc/lib/args/include/args/register/test_info.h b/buildcc/lib/args/include/args/register/test_info.h index a2e25dc7..dffda12f 100644 --- a/buildcc/lib/args/include/args/register/test_info.h +++ b/buildcc/lib/args/include/args/register/test_info.h @@ -17,10 +17,14 @@ #ifndef ARGS_REGISTER_TEST_INFO_H_ #define ARGS_REGISTER_TEST_INFO_H_ +#include +#include + +#include "env/optional.h" + #include "target/target.h" -#include -#include +namespace fs = std::filesystem; namespace buildcc { @@ -70,9 +74,12 @@ struct TestConfig { * @param working_directory Working directory from which the test runs * @param output Output from tests */ + // ! FIXME, warning: base class ‘struct + // tl::detail::optional_operations_base’ + // should be explicitly initialized in the copy constructor TestConfig( const std::unordered_map &arguments = {}, - const std::optional &working_directory = {}, + const env::optional &working_directory = {}, const TestOutput &output = TestOutput()) : arguments_(arguments), working_directory_(working_directory), output_(output) {} @@ -80,14 +87,14 @@ struct TestConfig { const std::unordered_map &GetArguments() const { return arguments_; } - const std::optional &GetWorkingDirectory() const { + const env::optional &GetWorkingDirectory() const { return working_directory_; } const TestOutput &GetTestOutput() const { return output_; } private: std::unordered_map arguments_; - std::optional working_directory_{}; + env::optional working_directory_; TestOutput output_; }; diff --git a/buildcc/lib/args/src/tasks.cpp b/buildcc/lib/args/src/tasks.cpp index 170bf1d5..8328671d 100644 --- a/buildcc/lib/args/src/tasks.cpp +++ b/buildcc/lib/args/src/tasks.cpp @@ -15,6 +15,7 @@ */ #include "args/register.h" + #include "env/logging.h" #include "env/util.h" diff --git a/buildcc/lib/env/CMakeLists.txt b/buildcc/lib/env/CMakeLists.txt index 1cc6c285..4bba5a42 100644 --- a/buildcc/lib/env/CMakeLists.txt +++ b/buildcc/lib/env/CMakeLists.txt @@ -17,6 +17,7 @@ if (${TESTING}) ) target_link_libraries(mock_env PUBLIC fmt::fmt + tl::optional Taskflow CppUTest @@ -54,6 +55,8 @@ if (${TESTING}) endif() set(ENV_SRCS + include/env/optional.h + src/env.cpp src/assert_fatal.cpp src/logging.cpp @@ -96,7 +99,10 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) $ $ ) - target_link_libraries(env PUBLIC fmt::fmt) + target_link_libraries(env PUBLIC + fmt::fmt + tl::optional + ) target_compile_options(env PRIVATE ${BUILD_COMPILE_FLAGS}) target_link_options(env PRIVATE ${BUILD_LINK_FLAGS}) target_link_libraries(env PRIVATE diff --git a/buildcc/lib/env/include/env/command.h b/buildcc/lib/env/include/env/command.h index 0c54a355..c054e6b3 100644 --- a/buildcc/lib/env/include/env/command.h +++ b/buildcc/lib/env/include/env/command.h @@ -18,11 +18,12 @@ #define ENV_COMMAND_H_ #include -#include #include #include #include +#include "env/optional.h" + namespace fs = std::filesystem; namespace buildcc::env { @@ -74,7 +75,7 @@ class Command { // TODO, Update this to get an integer exit code number instead of boolean // value static bool Execute(const std::string &command, - const std::optional &working_directory = {}, + const optional &working_directory = {}, std::vector *stdout_data = nullptr, std::vector *stderr_data = nullptr); diff --git a/buildcc/lib/env/include/env/optional.h b/buildcc/lib/env/include/env/optional.h new file mode 100644 index 00000000..ed594535 --- /dev/null +++ b/buildcc/lib/env/include/env/optional.h @@ -0,0 +1,28 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ENV_OPTIONAL_H_ +#define ENV_OPTIONAL_H_ + +#include "tl/optional.hpp" + +namespace buildcc::env { + +template using optional = tl::optional; + +} // namespace buildcc::env + +#endif diff --git a/buildcc/lib/env/mock/execute.cpp b/buildcc/lib/env/mock/execute.cpp index 642411e4..7fc7f59b 100644 --- a/buildcc/lib/env/mock/execute.cpp +++ b/buildcc/lib/env/mock/execute.cpp @@ -12,7 +12,7 @@ static constexpr const char *const STDERR_DATA_STRING = "stderr_data"; // command bool Command::Execute(const std::string &command, - const std::optional &working_directory, + const optional &working_directory, std::vector *stdout_data, std::vector *stderr_data) { (void)command; diff --git a/buildcc/lib/env/src/execute.cpp b/buildcc/lib/env/src/execute.cpp index 60fe41cf..4281d442 100644 --- a/buildcc/lib/env/src/execute.cpp +++ b/buildcc/lib/env/src/execute.cpp @@ -28,8 +28,8 @@ namespace tpl = TinyProcessLib; namespace { -tpl::Process::string_type -get_working_directory(const std::optional &working_directory) { +tpl::Process::string_type get_working_directory( + const buildcc::env::optional &working_directory) { #ifdef UNICODE return working_directory.value_or(tpl::Process::string_type()).wstring(); #else @@ -42,7 +42,7 @@ get_working_directory(const std::optional &working_directory) { namespace buildcc::env { bool Command::Execute(const std::string &command, - const std::optional &working_directory, + const optional &working_directory, std::vector *stdout_data, std::vector *stderr_data) { env::assert_fatal(!command.empty(), "Empty command"); diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index 1b764920..816c5b2d 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -94,8 +93,8 @@ class Target : public internal::BuilderInterface, void Initialize(); // - std::optional SelectCompileFlags(FileExt ext) const; - std::optional SelectCompiler(FileExt ext) const; + env::optional SelectCompileFlags(FileExt ext) const; + env::optional SelectCompiler(FileExt ext) const; // Recompilation checks void RecheckPaths(const internal::path_unordered_set &previous_path, diff --git a/buildcc/lib/target/src/target/target.cpp b/buildcc/lib/target/src/target/target.cpp index 6a2b6a98..5958b556 100644 --- a/buildcc/lib/target/src/target/target.cpp +++ b/buildcc/lib/target/src/target/target.cpp @@ -89,7 +89,7 @@ void Target::RecheckExternalLib( std::bind(&Target::ExternalLibChanged, this)); } -std::optional Target::SelectCompileFlags(FileExt ext) const { +env::optional Target::SelectCompileFlags(FileExt ext) const { switch (ext) { case FileExt::Asm: return internal::aggregate(GetAsmCompileFlags()); @@ -106,7 +106,7 @@ std::optional Target::SelectCompileFlags(FileExt ext) const { return {}; } -std::optional Target::SelectCompiler(FileExt ext) const { +env::optional Target::SelectCompiler(FileExt ext) const { switch (ext) { case FileExt::Asm: return GetToolchain().GetAssembler(); diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index 6bd916f7..389b54d1 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -18,12 +18,12 @@ #define TOOLCHAIN_TOOLCHAIN_VERIFY_H_ #include -#include #include #include "fmt/format.h" #include "env/logging.h" +#include "env/optional.h" #include "toolchain/common/toolchain_executables.h" #include "toolchain/common/toolchain_id.h" @@ -51,7 +51,7 @@ struct ToolchainCompilerInfo { }; // clang-format off -typedef std::function(const ToolchainExecutables &)> ToolchainInfoCb; +using ToolchainInfoCb = std::function(const ToolchainExecutables &)>; // clang-format on template class ToolchainVerify { @@ -74,8 +74,8 @@ template class ToolchainVerify { /** * @brief Set ToolchainInfo callback for run time objects */ - void SetToolchainInfoCb(const ToolchainInfoCb &cb) { info_cb_ = cb; } - const ToolchainInfoCb &GetToolchainInfoCb() const { return info_cb_; } + void SetToolchainInfoCb(const ToolchainInfoCb &cb); + const ToolchainInfoCb &GetToolchainInfoCb() const; private: ToolchainInfoCb info_cb_; diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index f93867a4..9d5361b8 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -17,7 +17,6 @@ #ifndef TOOLCHAIN_TOOLCHAIN_H_ #define TOOLCHAIN_TOOLCHAIN_H_ -#include #include #include #include diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 4c22aab2..7189ecb7 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -16,7 +16,6 @@ #include "toolchain/api/toolchain_verify.h" -#include #include #include @@ -82,7 +81,7 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { ToolchainExecutables exes = CreateToolchainExecutables(toolchain_paths[0], t.executables_); - std::optional op_toolchain_compiler_info{}; + env::optional op_toolchain_compiler_info{}; if (GetToolchainInfoCb()) { op_toolchain_compiler_info = GetToolchainInfoCb()(exes); } @@ -98,6 +97,16 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { return toolchain_compiler_info; } +template +void ToolchainVerify::SetToolchainInfoCb(const ToolchainInfoCb &cb) { + info_cb_ = cb; +} + +template +const ToolchainInfoCb &ToolchainVerify::GetToolchainInfoCb() const { + return info_cb_; +} + template class ToolchainVerify; } // namespace buildcc diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 19110e05..96d00d6a 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -110,7 +110,7 @@ TEST(ToolchainVerifyTestGroup, CustomToolchainInfo) { buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); toolchain.SetToolchainInfoCb( [](const buildcc::ToolchainExecutables &executables) - -> std::optional { + -> buildcc::env::optional { (void)executables; mock().actualCall("SetToolchainInfoCb"); buildcc::ToolchainCompilerInfo info; diff --git a/buildcc/targets/include/targets/target_generic.h b/buildcc/targets/include/targets/target_generic.h index 0d5d5ed0..0246c1ac 100644 --- a/buildcc/targets/include/targets/target_generic.h +++ b/buildcc/targets/include/targets/target_generic.h @@ -18,7 +18,6 @@ #define TARGETS_TARGET_GENERIC_H_ #include -#include #include "target/target.h" #include "toolchain/toolchain.h" @@ -137,7 +136,7 @@ class ExecutableTarget_generic : public BaseTarget { public: ExecutableTarget_generic(const std::string &name, const BaseToolchain &toolchain, const TargetEnv &env, - const std::optional &config = {}) + const env::optional &config = {}) : Target(name, TargetType::Executable, toolchain, env, config.value_or(GenericConfig::Executable(toolchain.GetId()))) { switch (toolchain.GetId()) { @@ -163,7 +162,7 @@ class StaticTarget_generic : public BaseTarget { public: StaticTarget_generic(const std::string &name, const BaseToolchain &toolchain, const TargetEnv &env, - const std::optional &config = {}) + const env::optional &config = {}) : Target(name, TargetType::StaticLibrary, toolchain, env, config.value_or(GenericConfig::StaticLib(toolchain.GetId()))) { switch (toolchain.GetId()) { @@ -188,7 +187,7 @@ class DynamicTarget_generic : public BaseTarget { public: DynamicTarget_generic(const std::string &name, const BaseToolchain &toolchain, const TargetEnv &env, - const std::optional &config = {}) + const env::optional &config = {}) : Target(name, TargetType::DynamicLibrary, toolchain, env, config.value_or(GenericConfig::DynamicLib(toolchain.GetId()))) { switch (toolchain.GetId()) { @@ -213,7 +212,7 @@ class Target_generic : public BaseTarget { public: Target_generic(const std::string &name, TargetType type, const BaseToolchain &toolchain, const TargetEnv &env, - const std::optional &config = {}) + const env::optional &config = {}) : Target( name, type, toolchain, env, config.value_or(GenericConfig::Generic(type, toolchain.GetId()))) { diff --git a/buildcc/toolchains/include/toolchains/toolchain_custom.h b/buildcc/toolchains/include/toolchains/toolchain_custom.h index bf061697..dd43dfc9 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_custom.h +++ b/buildcc/toolchains/include/toolchains/toolchain_custom.h @@ -26,7 +26,7 @@ class Toolchain_custom : public Toolchain { // Run time basic constructor Toolchain_custom(ToolchainId id, const std::string &name, const ToolchainExecutables &executables, - std::optional op_config = {}) + const env::optional &op_config = {}) : Toolchain(id, name, executables, op_config.value_or(ToolchainConfig())) { Initialize(); diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index 22764d96..60b15058 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -35,8 +35,8 @@ class Toolchain_gcc : public Toolchain { public: // Run time basic constructor Toolchain_gcc(const std::string &name = "gcc", - std::optional op_executables = {}, - std::optional op_config = {}) + const env::optional &op_executables = {}, + const env::optional &op_config = {}) : Toolchain(ToolchainId::Gcc, name, op_executables.value_or( ToolchainExecutables("as", "gcc", "g++", "ar", "ld")), diff --git a/buildcc/toolchains/include/toolchains/toolchain_generic.h b/buildcc/toolchains/include/toolchains/toolchain_generic.h index 75b835f4..76adfb38 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_generic.h +++ b/buildcc/toolchains/include/toolchains/toolchain_generic.h @@ -32,8 +32,8 @@ class Toolchain_generic { */ static Toolchain & New(ToolchainId id, const std::string &identifier, - const std::optional &op_executables = {}, - const std::optional &op_config = {}); + const env::optional &op_executables = {}, + const env::optional &op_config = {}); }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index e5685272..4b019169 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -36,9 +36,10 @@ namespace buildcc { class Toolchain_mingw : public Toolchain { public: // Run time basic constructor - Toolchain_mingw(const std::string &name = "gcc", - std::optional op_executables = {}, - std::optional op_config = {}) + Toolchain_mingw( + const std::string &name = "gcc", + const env::optional &op_executables = {}, + const env::optional &op_config = {}) : Toolchain(ToolchainId::MinGW, name, op_executables.value_or( ToolchainExecutables("as", "gcc", "g++", "ar", "ld")), diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index d6fb156b..8fbb8fdf 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -35,8 +35,8 @@ class Toolchain_msvc : public Toolchain { public: // Run time basic constructor Toolchain_msvc(const std::string &name = "msvc", - std::optional op_executables = {}, - std::optional op_config = {}) + const env::optional &op_executables = {}, + const env::optional &op_config = {}) : Toolchain(ToolchainId::Msvc, name, op_executables.value_or( ToolchainExecutables("cl", "cl", "cl", "lib", "link")), diff --git a/buildcc/toolchains/src/toolchain_aggregate.cpp b/buildcc/toolchains/src/toolchain_aggregate.cpp index ca5fa13e..6a9526b0 100644 --- a/buildcc/toolchains/src/toolchain_aggregate.cpp +++ b/buildcc/toolchains/src/toolchain_aggregate.cpp @@ -29,8 +29,7 @@ namespace { template -static buildcc::Toolchain *AddIf(const std::string &identifier, - Params &&...params) { +buildcc::Toolchain *AddIf(const std::string &identifier, Params &&...params) { buildcc::Toolchain *toolchain{nullptr}; if (!buildcc::Storage::Contains(identifier)) { toolchain = &buildcc::Storage::Add(identifier, @@ -51,8 +50,8 @@ void Toolchain_custom::Initialize() { Toolchain &Toolchain_generic::New( ToolchainId id, const std::string &identifier, - const std::optional &op_executables, - const std::optional &op_config) { + const env::optional &op_executables, + const env::optional &op_config) { Toolchain *toolchain{nullptr}; switch (id) { case ToolchainId::Gcc: @@ -73,8 +72,7 @@ Toolchain &Toolchain_generic::New( "ToolchainId::Custom and ToolchainId::Clang require " "executables to be provided"); toolchain = AddIf(identifier, id, identifier, - op_executables.value(), - op_config.value_or(ToolchainConfig())); + op_executables.value(), op_config); break; default: break; diff --git a/buildcc/toolchains/src/toolchain_infos.cpp b/buildcc/toolchains/src/toolchain_infos.cpp index e17eff18..1b7a1fc4 100644 --- a/buildcc/toolchains/src/toolchain_infos.cpp +++ b/buildcc/toolchains/src/toolchain_infos.cpp @@ -38,7 +38,7 @@ buildcc::ToolchainConfig GetGccToolchainConfig() { return config; } -std::optional +buildcc::env::optional GetGccCompilerVersion(const buildcc::env::Command &command) { std::vector stdout_data; bool executed = buildcc::env::Command::Execute( @@ -49,7 +49,7 @@ GetGccCompilerVersion(const buildcc::env::Command &command) { return stdout_data[0]; } -std::optional +buildcc::env::optional GetGccTargetArchitecture(const buildcc::env::Command &command) { std::vector stdout_data; bool executed = buildcc::env::Command::Execute( @@ -60,7 +60,7 @@ GetGccTargetArchitecture(const buildcc::env::Command &command) { return stdout_data[0]; } -std::optional +buildcc::env::optional GetGccToolchainInfo(const buildcc::ToolchainExecutables &executables) { buildcc::env::Command command; command.AddDefaultArgument("compiler", executables.cpp_compiler); @@ -94,7 +94,7 @@ buildcc::ToolchainConfig GetMsvcToolchainConfig() { return config; } -std::optional GetMsvcCompilerVersion() { +buildcc::env::optional GetMsvcCompilerVersion() { const char *vscmd_version = getenv("VSCMD_VER"); if (vscmd_version == nullptr) { return {}; @@ -102,7 +102,7 @@ std::optional GetMsvcCompilerVersion() { return vscmd_version; } -std::optional GetMsvcTargetArchitecture() { +buildcc::env::optional GetMsvcTargetArchitecture() { // DONE, Read `VSCMD_ARG_HOST_ARCH` from env path // DONE, Read `VSCMD_ARG_TGT_ARCH` from env path const char *vs_host_arch = getenv("VSCMD_ARG_HOST_ARCH"); @@ -115,7 +115,7 @@ std::optional GetMsvcTargetArchitecture() { return fmt::format("{}_{}", vs_host_arch, vs_target_arch); } -std::optional +buildcc::env::optional GetMsvcToolchainInfo(const buildcc::ToolchainExecutables &executables) { (void)executables; auto op_compiler_version = GetMsvcCompilerVersion(); @@ -132,7 +132,7 @@ GetMsvcToolchainInfo(const buildcc::ToolchainExecutables &executables) { // -std::optional +buildcc::env::optional GetErrorToolchainInfo(const buildcc::ToolchainExecutables &executables) { (void)executables; buildcc::env::log_critical(__FUNCTION__, diff --git a/buildcc/toolchains/test/test_toolchain_specialized.cpp b/buildcc/toolchains/test/test_toolchain_specialized.cpp index f6d47256..bb316ec5 100644 --- a/buildcc/toolchains/test/test_toolchain_specialized.cpp +++ b/buildcc/toolchains/test/test_toolchain_specialized.cpp @@ -2,11 +2,11 @@ #include "env/storage.h" #include "env/util.h" +#include "toolchains/toolchain_specialized.h" + #include "expect_command.h" #include "mock_command_copier.h" -#include "toolchains/toolchain_specialized.h" - // NOTE, Make sure all these includes are AFTER the system and header includes #include "CppUTest/CommandLineTestRunner.h" #include "CppUTest/MemoryLeakDetectorNewMacros.h" diff --git a/buildexe/CMakeLists.txt b/buildexe/CMakeLists.txt index b05801bb..6d4f9a9e 100644 --- a/buildexe/CMakeLists.txt +++ b/buildexe/CMakeLists.txt @@ -21,6 +21,7 @@ target_sources(buildexe PRIVATE ../bootstrap/src/build_spdlog.cpp ../bootstrap/src/build_taskflow.cpp ../bootstrap/src/build_tpl.cpp + ../bootstrap/src/build_tl_optional.cpp ) target_include_directories(buildexe PRIVATE include diff --git a/cmake/target/tl_optional.cmake b/cmake/target/tl_optional.cmake new file mode 100644 index 00000000..f7afb525 --- /dev/null +++ b/cmake/target/tl_optional.cmake @@ -0,0 +1,2 @@ +set(OPTIONAL_ENABLE_TESTS OFF CACHE BOOL "TL_OPTIONAL Tests") +add_subdirectory(third_party/tl_optional) diff --git a/doc/software_architecture/buildcc_interface_lib.PNG b/doc/software_architecture/buildcc_interface_lib.PNG index 6fac4da17e92298a77b44612286e647611123e87..ec3e12435751789dae816a7bf9e8cbbe85db6435 100644 GIT binary patch literal 156596 zcmcG$cU+I{|302g3DG8_qK(oL8SOIKdrN8Wp|nJ#RGMaKY7ew0l91324WYc+TB7+q zPWSzOzkUAy{oJ?5eaq{0UDtV@&v87D=kdI*shpOlrDmn3qN1WzRFF}lqFT3-ifYC4 zwX5-yiHeja{Acx<6Y?@tOXQz~%Csmds-0AdGRHN}-y81oG>D#_T^bkT9Sx3*4or+F zO)B}CU%EBG(wZh!%Q~b;=R?wWZxO!2;j{5!BdJ_2ik}K(mI~v9F74hD2otUGv zD!s0+-;~*gO?O|vkzAkm{p-^erlX}t$F|D#$KSTet>3k8-#%qL#s7W{ONk_}_}?G# zf9c}%E0_KK6ZgvjJOBRklQ5M{Sl9o4brBP}gmcz*m#@N4os8YPX%@_gdr9TevO-dxK?nk^u9 zpK-23^+Hk7Bl2^G!A}m=trLCqp<(~s7!ysgmR$;w+r22e1Psdx*#G&U^|zN1a`OMZ zR({#m!T-BePm2D(**lfMlm`#2e^2zW3Y`sVRQ>NAsi+v$YA94xCPUk{Z3|xTH8P5i ziRvsFXigi7Qa&OmK`im#Urz!kcsBEw_4UoKqPQB2?;rBWRbyPC*i^T}&(`&?1NIM8 z#RvNwCmY1>E{%NqcGhI`f3AW5D#_!lb&gqEXLkF{7#)&(Q>6zrvzq>sHv+LdjEE&Wf78zq-SNd?(TmX!4dc~B0fI1um0xUeacEo zkKWV$Ws$b4U@9t4@xAE|v+!4~t(u;mo?eT;zqjTYA06qg)Ne9gb$DTRy7}nRZ{@ze zKJtm;PUjG;|J&!!D*Z>cUlf*(JNFs`|hs?FfoKF9$OW1{kn#wWxAA<6sMxk+|L+JpP4R?$g`uv z&5zG1D+)P?oqM|tw~r|e*UZwo-Tu1g>fO6{IS0tD8#A)9X1;%~Qu*TzR#Z%tePKKeRyQK8=;h_qwTX_R7U#9

xb#7I0?;2Vc+@l#7gY#?ITkR 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 z z-6!!-ugq`hh?KN+@91b4@Yosff6%tmBEph->pG?Z(r(`7!s*T)!0j*<#jjVe7KDc! z0*N37L=`wUXB(C?qDIRta6!A09t})pQCnt|wVGCSt-GxYS#i!!QB}~fu^B#`W?c}$ zx(OcKFDly4ct(N(Ju=x?1ZSJ)jHZ6(pPyVTIX})07A+i+=1F(=b|_9|G4ntvP*OKA zxDI{GGyD+z?Grei6GkuzE_VIM2gTbicJ}3vTU&OOi5!{#A+4jYZw43*d~}6!*tEr3 z1e8@ERFO%5r81|PODe1{)Ga5KOo+>2?k}Z=h?tl_kP}Q`cb>`b z@VN|!2s+(DjVJzvwD9o4j6KA`Pf^CWZf>;UY_ zqu&CM;M#TTj-Nca9)&?5P~a{R5e87*XfR&Y;FWzBFFB6ZU^03?MD?E9&7H9U!Y(JU zKSXLM?lUWlI_AgJfI2Z4(8F*td7PPN@3o+U)jfHeBSc@meCc0VS^46v$55NVHV7R< zeI3-)HoK2@UcB&+m`~US*du2*Cy%%j6SCsCjK)`hGG&~`Q~23? z%u>C%e{=^9j6sYR%!daW4tfHKjRiV|GrCEY}vgN_rfa zswO&aanwm2!88ngYk+d2>9cWU7Z0oi}@K}gl{@JI{F*zU8-;YIn=%poYgNV z7JCNgVTU@!_H1ZU2f>}qAd8@MJp8(KM|corBX0~fs_17hV!EwcLy*@J0jwzPc{`wb zq5-=IXliU}cKrA<%;kkbioETR`+DlYwrWs!n{!ZDZzrU`<< zay)teeiJ5`_IgcGE`s<^MrcATZlK9}X%&@}M8=D^L$083^5k8oI-HEX8-`!u3t|dCo`o4NzsqV$r|JhVm8PLA*bO-N!HiNfpH*S za0m%)MmeCMr1T7pctK#;siF3yA&+PUcO?_Ydm1~x=O7bh2&88Yy# zLmu{_`h8JBnQzg$bHqd|#$B=gWoRV^AX*}MlfpcBO%QteYiw+Wly*E*&Cr03PRh$m z0#IE;@R&1@80`4MsNDxEu$8jU*mm_Z9UWdF3K$3(k$gt6T zdiXP{E^(Ez3ikA4eEcbz7j#TabprNCQj{F0ok2m?m~-EZ zaB2#@V~KMgHGwxMdXjNP2cKcorD#g7gB{hP)WZ#R1ubFFY|$|>niWMrhv;|;qLjW4 zUrI)7wS1qj?9H1uCbqT)=eCs#Pjktw=<*0L3cE)z6+u9rm4P zMyfjh>&Gszn^1XP1&0}IdjIIHyLXe}=J}5v1?1$|)$VWJ!BivcM0Y(XJ@dx`FP-KU z#6-O2U=?hj#C?R7pP&D8U*9Seq%h6Ak3A*}7}2^e!ej*dTU zDi@I~)xLO8ryd}J?Ovcj89t4%N>t;GSx&f*q zjPf!f&oFH85Zdf)qe@nU#~SbpbSx~_U@w{<4+1GPLhLa$+BFyWE+#gXou7X_xbIqE zJ+d4?BN9b0&-w%^0hru1Vkn*yE5mmjeG$c_{A2jT0R_&;;1I=qW?1Wr6)PwM1Brk| z`-O#NAOlyy%PPnr^!NAYKYo0vwDivn@#+S=vSdBkHZ&uRy~ZJ^4hmX)hXM}{v4(&v zPtQceYY9Q&9IY%tOh$O4=;|o4+X}F`PhuU_4=7Geq2tymb>1Dj*KoG2uDQLv4(b8pM=+inOCnrbZSDEX;L}wis z3@7*_=0|#wgUOkayp3E_FGKX3{OY8gMiz1l+0#8mAVb~LxSCD(8(CSMu+ zJZM>kk70(Zk?axJwJ*K=z*NGv9V+U6D@BY@{an9(eZSd@_4uk8WX6D3DjFIqLCzag zoTmdkn55}RCcD{9za}6^Aq_)7W(ZZkK(rCqbn@2zWx%IWgzx+4H22f)%^eY%#l^*2 zs1@bjodPzHaj2`UT}37pf8+z$s^tfza*RJ-tC{01ePXqfgsN88xM z++34~4Y0HZGhw?T6nOj2%gE%B_v}y*`BSq`p49vv&Tx-kKw#8mdw{2=b!h={ldJ4{5N_=6x7t~w$}Kr%W8hComzUof+N`P#K>6wc5{1x^@~ ze$0Ig<^6Ej*y|0tuj7$94e^N#u>tY*WFwyVb=xqru$Y1%JpXf;1yjp=C9YW~tl7BT z1Z*9N8j$mZ0d)My(d=wB7k9EZ@sQ{YWd#9Xhy{Ogn6TAmgyG8~2)f4;RdxyrMtpLC zd(y3oMbd?6*#rny+;?7lJuPkT;9xMqJR+HtYy4@v_(Te<(^A`*ppeirphgo@Q&m|_ zJX=gnYbyilr=$ZE+LQ5zSztTNV)onc3V>Zvufz|ZWR1FeHw1Hqm^)*t3*RA+L?*+9 zTSjakKzv{&FajtJ2)j3mii-Y1jn_Li77lE%ZUnE#2|T%{1~_0BYL22!_)_axOz0B} zA_WQa)~#lsPDt(b8NPKamL1#~pV- zmuCn3h53NRdJ_F0YjNfd%IrkNDF}j&q#q0(T`nvvq;LZCG^uV|3*<8bBuGFiAkjG3 zrk#jS825bN-p&-aI#ul&eErwl90&TBt{d>Es-a|0@unCO9GHd9uGO|rVS@US5j+C3 zgey13r{A^`!>|rQpKcSL25?JSQE?r4#}q?5qoNpOg2@mqAUl!@5kw}>pBmEjRy>7@ zJ*oNxY9momMuK6SoSq`GB4AyG3>Ge8UAuAkZxdvSlg3GDdBpoQ|Mz<>*xD&5rON6m^RQpx`v-BHStr@I>?D8gN=AcK9gc=o7E&-A)!&^QO zVtY|gZ(B{EA#WW+KoGiG0s^w<&x?c8yNIlacXsunO$vq-5G(*wTio>2oO|}Pm25pt zEc*`8zzp|P?|_>hg3a%ikRLj0VUdJ&BTCoc{erUJEhTX$0%TFX`=dN0QZU<&{AK9l zY>AV@MKs@Zb+Ms4&V0mM9N_*6j`JDXC9aGEYg5(MA^YRagBv06*n$wu{$~%ZsWz;n zi)h0zB@1pE2v+cThQ=B2g})%ZyoQSZ+UW}!P)~ZNc#o*$rPtec1m1@Q7NR6NAIrO3R!>*0737_NGOs`O>J%9 zrDJ}P(a|gMjyk*-Xc=ON3^Ir;mu4`Au~wnHYgvCKRwwy8**d3kWFi1lT3aq!BBlN{eUaHWy=c%ubI-}GFswBbz%%cwS- z-hv&s;`wv%K;;1^_efh>aw8n>zwp!cXNl@XwaqCw40Wm`?JgDFm zqNpsFWhLrjQ&Q)`dogTaa`r4|0cL;ckxo%uUw!y+T%QfMS_j1U3??6e*ZnkJ+@E_4 zqtzMpVGEwcGnH-fl)1S%XsTr}wi*;4GT7n>DwrHf zhdY$@#2(p`n1~$$j1T{K7*ivVPu?TR@~b73T#>d5S7U`=e72 zGLHyh1QCHqiA(r}z@Psd8ZNwWk>JTxQ~{eO< zVD$tb6HfdKl$WZO)*cBmnVQdqeNe9TeQ5eKGAqIaz*F~q?T>#pcP#*OMPv8h7 zrehCD34;eZm7&4DfBz;xytQlBZu*mvQW$_M;B1TEZP5QtO=RuDbl4S~R><4)0*^*L}1S?ek|)tX_i<<1>5%LgqDS`*BF*sikZ1{`&p<>9c3c!N>m- z=~Yk)bre`_xp(g#Of-a4_NSYyU^~nr*7V4qE4X8n8V~wG-M%Ijy&E8ak0Ri;P&0u`uu9Qs#n<1Lx^++cFkFGa?>v>(*|G!9zN@X6RQX*q! zAx$V5iZUz7Sf*4cQ>D>Z$Q(*Y88T&7l$j_cvy?@HjG0xx_no!&+2_B`f4%l=pM930 z@Avb0p8L7(>$>jiA&w^Yv-bnKpS*&C732%#(V)^CYe$!DR#Q{E2e8a+(v+zUf12}` zoaF!19$uny0ng?_6b~=|6rlPJMOm=9-#mf5)+1?*Md@vt3uIaLhAJe@{9t`!)^4QwTQ=cJ^ zHl|hutJkbKIj5!+=c<1a#>%>x`-({pD;paXS?{brX%VP5q2Rp26UKWSjWPSGU`bF? zQVOej9NL$!Usu66W=#VLP_L8OySwF_IUTV$NE5N6muGd7%rv9rvsOCMG|=-reEfLj zFnN^v`hIH#JS8}jRT98Jz;1MNDR&?+f4D+=5{vzz0glEEh^z$RRy#AHhv z*v5)3ss?C;yru%Enkw9r)deLN_2A_HDj5~)#~r%L>0U)5b6hR@S=N?(yhykL_Ne9X z;onlCa2W{-hn?QHZ(ppJY$oH0zP`OHhy&1LkMiLfL|au(b$72_t5&TYW=op_kz>71 zi~}Vyuhhx3pc5_prALpN&`bQ!tF;L&s+hP$-_MO1ew8|Ptk~JGAi;U+kIz(K3d5NF_;HR=pSgdt&j-Kx`J1kJOENtE|S zoc)lL>a@ncv5;#=f9iiA$DP%Bnd6y)<9>3SwEP!p9&lWVP7t1 zU;u9*%M5~D&fh6rn#_5AUKO7DHzq|0(>;aV){Hccf`$xAN$F4En3QF9_DX1K`3OSE zQfe{}j_r!WQ<>ulem=UeZ*0#jNB9y4Z)dB@GGs#a%0H$OkW@4_-+o7STQbAobIG*^ywpG(O-z2rw1sO8qCe=Vo+ zgHr4$>JlqYJ_cj>vBzZ*$UlF&Ov3P1APQF>HENWKhQ?J&mS`Y?Z?9e*=)JQusaf`I z>hs(E;SM;T8{N*>^^X^T`Zsvb{{5i<4C{ddC(|iawJO%8GGo`Kef#W(Ki-y>eq^S@ zm3;*9aPOh-3r9d4d{%W*WEvOeEqNa|EU?v?O@X0y-2C-@8X6ZAf~CG4#|j@sPhA+JD$a`Q2_kH%XGKVW;> z-aF_0AJ8Rt0XTbQR7=`W{yOLTEQY+-uR~DWoxKO|HKuRj8z7AB&io8$ZRxV~O9K#u zKYPHV?CIPBve_@;GPM31K5@dY<$Q5apa1pkSfGa>38;1|B6_$ox~MWdb*Aq)i@hT* z-Mw44VZ(+kHY~&UB4)8V7P`Mkpx{((%W78Rx(m zD9j6LSSUJ^za?}a%wN;~J!L=1Kao8;YwDO=JH5yABONMpQ}>9O=e1wHf4`n~xV87T z2dcGe2U^CMPoAugVDtw!U62|jCnD@-9v?>_9iSG@V>gO}={n~$LY6AlI_yUQ2d;;>6fM?sIy`Al|=!RbZ~);oCcplGp~O=QiM)do~%nQ(B6DkjuC zJCU(B;AH8xHr+q?S<3R3 zFzWfE&PPpxZ?&wtoMo=) zbEbzLtNdq~%pFDDjhqK9EqoMJD};5K4;u?Nww{AvxOd<{fN%^7X>3>Tz<_{im^Z`G z4_i_eNW7B}$0|K|rnPnVor#I<2tN5|?_BU7AEMW z3+EE^2mkZmYo+@bOUvraVNaSpdkvEQWX7t#gP*{D7fg7qJBUK{4jK0G>(_y(KP(Tp z&_K4%N|dXFj|{ek(UGjIf`%Z0YE+Sgtw?B-et-Wc>OW_ckhw2$z6u`a_qQ=UGS1;& zXOV;YNu*|Jo~3Q)G!cdkIM{xCvKoat_H&r`RgRP-a#u2&%)RsAK|^U2V8zk3Ju&fC z87^dPTE_*Sp4!-1#xVZ$*L+3&EKAuD^M#8OFA6du;?yJ|si05F%1)=| zKKY+T@K3F9P)`OLW~w^Yq&@Zg{Ca4wK7CdVi>WL|L=CCiaxJ>rWJGYd_WIFf4|qk^ zM*s9Hk(=_Zt3@^(k(d*jJA+RdL;Egb^Q(_#*JIK zobfUgi&O?_fpP&TW%~4NH0RpU`|ELHF#|7DBmSi-WE+=8Ys|l>i+qFd5uTx^Zaa8z zAl(H!PqSXVR;Hm9=@@OKB2g8-zc6H5WsWz+2!LU;?VldjSz5Dkc>oC!**IQJFxYq( zW!2<(7Euz=GvG~;+P`sw4s)R)LSTq6{oqhDqPG3fNiQLLdN-Y!iawW#byzAtMJpa# zWubvzI4wXbV7L;zVZGn+00(0I1`PmQ@|NWv3jnskJ&su|qLu~0Z0%Z$XhAJjB2tuVQVgg!mU{mD`G+rGt}sw?y;^6*o4dOP@e>f4Tbcf~SJnW% z6eL*Kumjrk>j;OPJ9jqccl@(cP22VF-x6QQpJtb%W|FR{e|+m3(CB{{Bq*^^X~xhq zpAO!=vTf90oSc^-n3;a9I__<1;jgUSa><8kFLHD2zkdCS^4O4w5#?}eebYhh=m)J_ zTv{SQHHiK+0{B?9m>u?tEd_bljrbB_oB&uR5LFe;4D}PH(4PeyI&|p2I}V!~+#wMr zR5~CTx*?s?85joMDXAR3wnrBRilRU0?ixg z=}J;$9-nL{4gvUpNw6TlmkqFX3}>zjj^OWgA68iNX_wXUwV6O~D4bpPfqEig(@eYs zY;J+(2o30F@b8tDV^8abYPOQ8)m6jv5_*UZj*BiVV|OKf{MIy}!fMm8|7rfJmbH4` z9zScRy#K;FTr6WfXi(a-XVG@YJ;wa0B-m_J|7mLywz7}Jat3e3H*Sa*$6sv3-VNbI z$i)oM?NET+AtqT;RkflmDI}(sZ{A#)c2#Q1xYg}AH`l{pLM=!ZgV6ayh71uC!0%r# zDnmj;Yw`Vt{F~s&!5vYXUQ(p{^z`&esPFd1QLyiIt@mp=HREhefUuEr+TbT3*0W9nUAls*=fv-L{3S)cC8lIuUHUh;5vP}k*RHo?cNcj z0XukKeKB9yW~OTauYaDtJa+4{2NbZfo&^IhR`sc(d zQUNDj*oQxHGCiB%MqYO3r9ZueC9YDC23Gzbh%wf^BN`W8#?woG^$>yqdsNu4SYuK^ z!sz)YgUJM8Lqk~`&CC{5i;93CtH}tH@L`U#Dc^cVMz!Gb=;jl496#Qbqd5o->B6V( z*i0@{wL8>145dpea_drvnNI`cOxIW5!gMsD56t!%1-j!PT%@ zv%)A*tvYq8i_Wm*uOn;`;l&Qf+f$Ne1{wsFUyc`ToXP`?2~-hK{IC_C~S}Q|Is7xboCFrwzq%>30!3}Qjk71aR~`6 z_`5C^HeYk>=+R4Hk$YrNoj!e9myEqC|G~_y93`o#dCTYarNhkQrkt3nQu5P9R+tfO zY#QNFAD9&p^rup{?jTsKt7~=YV4}_REz{<1pNJb%=-(m+@BLHL>maSWQt|~j;-X)L zIkTxecj6N(K2`7G0F5Ov1wc{}2N2+zqTcjn*1Q%~6#c}Lm1TvEOL%Rll!HVp^GPEg zY#6+kj(R7Rea&|W5lGjsH}BdRXnU7Fjv8Mm?|r5!54IXM#X*ja^_dh1=SA*0cu)`(o?%@Na zIjS=NrwrNE{paHASS&c30$3n>PMkO~uyQPGD6>*kMa6u?h%CGQqn(}Ca&F8xT~*4Q zgKzD$UsHzBK^hG?gFCxcr=JO-YSAXoZyewB?*^HLyX!mV<=EO{C4h19{k+X4f}c`= z7!lj``AP_0D9iB$rwkAz)c`-=%Qx~fjL*C04dNVU1_Isx-aL6#S{G{93XC7v7S9UX zeUh8o3K+3VX=yb;DG!+&Sd(&Z{4+r1A3XE<{aX2~Hg@9CKv{;_`9tc(R|$>C^FbFc zR(Q1>otOhd+Q<=I3Cx7npP=>b`Gr;d)iDT}yu&SUuE6xF29JNkE}J{zKV8hXxYl$- zuH;O0W@d{mHq^Uzkw4aor)Pca=$>xeU(T}N%wq^iKo=9L^t8Aw-Y{U)=S{l7H6tO$O~BtQ*Y$!5q9 z5hn*2IdrELG!;Hif~Q7$4~ApHtyv{JhIwx}b?Tef_?1l?H%>+91r|3LQ}x}KUk%XB zvL#eDl~t4p*^RHdK4km=`UCLFt(Jom!ueuDFtTHKxVyCP{{kS6;y>LsAJSOvX%hpx zkb}573Sd1TvNfXz<~#)HcgFK0S_2=nUi6-kJlIU~I_rtiv{7{J z+7-L)<(7G>2E2G7`h`go{g>Fy&zaH$LD^=8Ghz zff=*X0gK6vc?!jU7oNa6QXdmIEmUX|X{N4{f4YK`9d6ulf_Lkm=fK#cs00ucR2w^D z8We-IQPB=4{)Z1AhGpogkGbI29px|-LR3^*OD1_`KhrwJc_M%fgr-xZg83MJ3lya% ztne=NF=r?C#wAPol602`Faa#qgKVzn9oRx^`bQf&C zROZjU*JhlB!c|sltZTYwuvn#p{Mo*}*}&C}^-KpzjU-Y8akx6*pQ|#{kb(w?G8GvD zS5bpb_B4Nd)~s0sSgxa`S(#C_Ix6dqR*7{N*B3WS3<6>c4K3p#@QEV%ga&x0!}#pp z|LylFBeYIQ+n`~eT*sv9kLME65WqWyGt=W&@hHN@J9rO{TEq;H?DE^&d)B4(WcfB= zS8*q$?uHw(tj$v4bJzcensGYAViNl#FE()RUc<-9v+H1>z&6;PAq`mPfeg3E*)7&z z^s3kmRsNN};Xl_+?e$zXVKoIWGOD3|%fZkOF$A8~ zAL48CGG~gWLQ`8i5ZjhVmo*GY=v{QlnG;&KCCH;65?2jbt49p`^l2s)nbzwy@(%iMUIV8VT+d;)E2B0KgS@ENO7C zh?v8{EUQgW8^@j1p-~dD2(-4Kk-Ud15d)lc*=DIaj(g_a>YU{#@?er{4VlC4yZEab z65Q2)NVGKxslYw^5hFg`yjyuR_~DM;UY)tU1Uh`^UY3G`;TgX##`}ivT8lf0)iU|* z!=qv>b6&+Gmo^J32oKL>o;7v=rz>|mi>VRR1+doYV!!Cf_`VbcM|QK z>6(OlEY?YrCMlu@f62PrtZ7q`>^LgkbmoY5=>8e^UwfB}%@K=0y1f>>ZH(OC4r#e? z?$&;bdoWm($vuK%!a~4muKwj>NwpOacME&^(T7l0Fq z-+OqBC(&8cqRRJ*bel5+w(O7>^H6dI5cX|JI{Hx}Kt(3So*#QZekHvZ?PtpT#y0wq zsi<+(L2I!!P8jr97fuC$E{!!OA`ep^qNuPFo!Lu93kPBNhX@F{i*s;I$M*HK!pktH z=gH&*yG`-?&9uiY(Q#48-OEsG9fr!vpY-X~jRuKhQdYyiQ+8r58OK&0f^uht+*MZ~ z2#V>o@Y%VZ7(Z+A>V$s6Cla-+0!iu;2PoBD;SXALnq{&8XN{aUJZPD6x#AxI-$fJX zT-1T3Zrxq=Na}_M%fh+5)RS|GYr5eMC}B3Ll7I2VK0$!lg7f%Yp6r<3#I znbQ&~h|TxJsK>)8kgI9FC^-+E;^9$8UI11NsIK#uhFOoB&cvd$wn7h~MXw*ebVL+^ zo7%#GA zcFsJ#y0DU){R*i3;-C|cB=1`fJ_l>7|Ar0q=sh?KRUb%830FG?GF+&B3 zWJ1a^9aQB8Ex92%kP0uugZ%v(kt6p$zOc9_uvL+Fro-imVFTv3;p_}>C?YG^^b^(iprZWr&Vcdhm^NRlXE4QU13gL*;~`$j*x8x_7~tK zl(|0UUlsU>olhT$;eZyu2bD}wc_z~hCkO+-vITxGj47D&;^G?keSKqNGLBVcn2iJk zA*SH;q(2>Yu%UD~Brrn0Nt{#2|Yu@y^|-sUKf=sE;hQ1 z(Q3DGV-=?VS`SHIK%di~#&AvpF^2*jC?bJaCCHaikya%Ccx&fq zqT*pNOyl3s%!)5xtw|RVodW+%HLV1pS4ka*BFWLwYT0rfIG`kb=>E}T8Kx2@;N-aS ztnH}^eAw0c^y#C%dFCmK*CmbsaP&a3^+UfR0xV{bL9~9Nz0JOP%1>$5Lk$%&@TSdZ z87Ao6`^;noyyVD5WrbQ0oS&X5>}mTw(pNVIQtgzxaMri5M5l5?r_Asn)(9sPq znsclD0mqvj@!#*BJR+I@lg$g!oiCxu+@mpG*}q+*MvXLPW4mxzLqF^1CT6H7r#iuC ztMJP47oPvHje}jcTelPWmp=eBO(0WFa9gFh=a*4q#)RR_e8~`6Sa`UF4E-9!NZN+1 z0K|_s8(NGzh)qiXCDVOiPQZ8F1CHa4Hh9QX{I_w#Bl?5jC?L{O@h~M-KHz7uD@BHW z!;*U8;;~yqZR%u$@vEe167&S>mr_$)d~@m@+x;KP-T&e;SRJ}M zzv)9m&C@GNfE|PH)MD_%*HvLPe0W`vUNH((v|Rj6r{R?|73(V1!@>;R+r;WNeOtdy z8=Loor;l~BsJAEGVAG6lSDV-S61RB%kmJ_FCl8t5?M)5ksN}4T$0k{rtG1c6H!Qx* zZWWtODg8f9UFLtTbLz3ZPtvx=c=RPEK}+``!8S17-tt%bDC82z*nY@XY5^E)#7y5nn#X}HPVy~(fq-puHfuT~QvrNOIr&HYTJpD~$de(tmuwuoBFWwgtfy^gvl!N>C@Y*!w+6>)DARcV{02=uA2%?DWm5f zek}R0sPF9^y*HG6sQ;X^LswG;o>)%VZasQjX0#6C1-WQyxj_bXPLpy<7?YeH)Gq|G zsXL8FIXRWS=@2=4&6+hBMVkr&pu?8MhPK8qUBLeRMv}WZ>K3zM8lWanWB{a}xsy`^ z;>7sNMGJ;z%)L9_(xx)DBH-FoaCM7y?Ij$WAcm{Gv?{U z-kvdQmNn;-_@#IwLXq))rWx1Tx_$fob?Zm0N5)aBxoPLlwK6Zwa6Xp%5E`6r-Mf$N zVAQ|=F56+fmsj+q#BF_5AHub;xcKYmP1pAWEW7Sn4sSYc+&BojGy~V8hhoKr%7U@d z)zrnp)xCRn>0LknfRg_9d6TBTZ?;R+>esKQ;q%w;+V!}V;p!gXJaHm?z*pg=sneuz z+qP|;aXkYEVpy8DW-@iLG9CVp`2PNG!U5u7Z?F658m&n8)y;cr3#AGP^fAk>lc(n1-)EMUn?hK~ zKn-{a!Ji)z?;aO2M!*b5;Aku z%9WRS=B|?`Uw*qCF7s&9@fQyt*1!~h`=T#rHhs{RSGwcJkB^U!w{cyiQq-*Y$l$94 z00on0@hUiG+vAZVM~X9`pM$NzI~mO+0qxoBF815aCgiVoKFcVv^xT-a(r({gT{183 zFbjF^#UHI~h5(eAy#KB!Fkiiw^>=#T#W%HU=Q)EAQ zu)s!vxkS6TxEQO{3%!>?vkhlwrSR6Fwx8=+#3v-wCc+|sKY9EvhTXBxMz`Xvs6;l{ zsA)ZBF<*z*(r2U9+~E`jwt*FLLv~J1?=bsiCz6xdv^6koT8?Afz9js5Sw z5!CJO?mi*3Z7x?ttYk;YhM`I?`tjFh!L)c_AOid!&*(&nl$N1-fC3|}bn`JWdLx5F zW)Il+^QWKeZibimMd|z@N45qvSiE@g;OFZj_U&s;i8itAhnZJYB`hnK3O?o)7G5u& za6c<65Rbt=zmatL-MV$lD=JcDe=_0Y$}OoQ9_m~At^Jv}bTi~Wkp>+%1o)@48(3Ua z#N^lJi_^o?vvYIPU`Fe|Bv4#ZVuEpw zA#>q8VEGquBiU(Q@wY1V9Hpr-7ZDNPNPUcS%p zLsn6$UX2HRT4TRUzvUIp;qn0fg_&y}gCQ;hJV7=38v-8l5%fs9fYse-eY(bA*#o=! z-&LzcY_}5U(x0;i>NP1L8R#1V(B%Z=!P)4|e>7tB=ul=AWW1Uf5!dd+!Ok0+bBAwj zA0MC7=gy^J8KemWxJ~Ils6z@|g-U?AKfnwp#%_Q+Mx!Cx_qfYvOounPL&Woda=}G| zAAbMv!j0P{XByb~ihJ+bwzfb?#s({OVGiyVMeRUa}bA@ zaOujTir>9+W6U9wDQjbrXKlT{eG9dRuW8}npv4{;)1fOJ8_;*XM%48!n>IBhiB1=K z57fsY9!gok7|(c35LqrZ1}3kVmQ07taOvezw`n((p+koPtFKDS3)3~30m!A!EsLV5 z0!qs(ei&gOyX4bm$IRKYuSj4D0I*fRemYEeMi$qrM4XijmvY?!DtaTbM>$Nvh=2Xg zoh#HXVJaV_EvWb7D-V#+2;H`ARaq+>bsRwcxZ5@;aB74?AJ5k@j`XMeQ!YC<2;z^1 z;_tE;IkFyXmW)V)YS4@02RE)-R4XsHR_flfr%2|wb;XbE(^$0N{zl1jKqItczD>kwwp4ZAufS2z$B`8d}5-T9Iq7k|2|$14Dn**LHc2K z9`9Y4db;_s9R@j$$byySb!KnAvvD!KC#eq8j%@IR9th=Qwd&hffc1=-GjX(Z7^mS;v{43762244S@)Lbe zSQfVFRR|~iDK~s<2!T;1TE8;^6~BpzVQg+#=(k*kZOB;)8=~x9(!WQ~o@v*whuMDO z{{}=DrPbBzFQ&3%V0i-Bn4r2TpZk1YjZ2B8mvP3mra{C-5nbnINI5_CM_3m zcS^;u?LF4`=de z1(9zu(~9G%ao za!kq_!7)L3iVqpSZ$juWgWYG(HU+~4*|)LA5Xp4nJ#-+pEYoH?4>V5ux~x&;+}Uqd zym~c-BSDatOeug}|I$#kWVS0-NsodXG;eT>cHp@2311ry4W^Pp0ht3cNp*RL~O6s1>{d z+K~9;sLBlFZAp)Ujy^sv0}@n5oH*#1qOZx#O#WbN>@(gP&A-ibk9aOP<>YUK6XEt)?ZhnxQ5(D6vo&tApJ^M|6WP}^ml93` z3$#yL;sD1QKFxXXK;O)4r>&A4`Q+fG8?<}$`0=rXpw{ZMRV|hlDr;$cnNoSfa{0*v z2UKO%8tqzAo%B)h>X7KQe(Ux?k%|!-czH=gvn?TM?p{`wB?1~pbDt#{v@io%j@jAS z5Ir)-hyKWP$-1--y6ZoEcxl!8<^IySoY%(f+Er6vE*mocE;8$u6dvZJO_>~vC;%F_ za6Mf@`OJLyP{ql~i9xHHxB;lL(<+8->sAz8@dS1E!@A|aYoxwt5Wod5Nfb+jqN%C< zuUovbf+&%RpCx4NiH)7{!-a5!UfOn`no&ob*Fb)`(rYZ@x~}+f9JOT*fGLPMkRfy&ZZNSkb~9u@F>zluEfJJ-MW3j zM3#3Ow>&5ClK4h}Dld^}Lm1U# z);%*T>(k})d>Y8Ffg?xWuVeTdEqH9*YTYzppu2_}iu1|Mtrh&;mUQjp;nfM03~utc z7$7d+o3r=(5;Fk(?tS|n+#RpK3w(ET$sFujTrQ!^D@uLyS(pant)x(kMlMqZtN~+V z<4F*&93E!7>Y~H6ofTdt-7!?Bw8Q)kI6+q!VHO6O5?dfJr)~~Mh$!#COK?t$zKi^+ zX`P+)>Egy3PPa8~Ya1yGn-$5l>g{`z;pwkXMDqZc{2+?Vs5i0fIw3Zw-JnR$ZLpl| zO^|{ZLmpT~f2lQCW&PYw8#N8;*Z%mouSPtvf2Uu0YTJ#bqTSBg2{DA|PIN>E{ zsrvVGcXKIIbd~`?-aibZ817D4Y;bPZsnaz!WW@IEw|?Kr$dKF*h2rt!$2#kM9*0yb zv3oLm#*9?_Hhm6$M(Sgx#he|^-jJ9IM6=5eA2#NXTt(GaC}{W|a)l~G7q|Qt*;)P^ z|0}^)i`$Q)PDDzF0oV$4(I9G{=yq_E)3yU4=AQk z!9w^6^^(W>9yzd z=`BtCjKRn(D*}R{9K(2%Vmgt`J>U)xKO!9=GzKR`;?^h@B&cPQyHMaMNeD zCMKLNPBRk{6J6ciZyM~py|dr;ocR=4YiENSQ+C|GJ!IcAX-{c1hMa7T{PCdw?dKPl zZa?sooT99fm<)qp?Z8*t`x+=wNnCjt_>n}H$C`DkZ}0ZE_=`WH@w-umAQB`l1Y5W= zwNm5st1$!Y9URa~cQi_<5Y;jD1xD=f{FQx_s1&tvBMFjQn$)%fm2$6m07E87IIrF* zH?G=sxGe=HaiQTrz$lj*t;uy>tj-4+UASsD7KE-*GbG9Y{~DNO1-mdUZBN=f)qFa* zR(R;;unr4LC2|6JNUimwbY4&G@v)7il+fhRlv=i_ZwdbA?w%o84YwO5vDd1~^vpzT znf$q0>#nU}by2COn9gixWE6U!Y(3Ns6Pc6#hq|FZ8}o;{sofj(0_x^vUS6t!SCUT4 zi6d-nO;6EQWFEg)N`rCh&3e=xb^|uL}y&{Nj&a z+#RI*qxCIS3;L0V$Y652Buvm`0xrl|+kEq^VOzY6k{t;mrW-oSRV2YW8lzfBQKeRQ zax5o_QCYFNu}Prq*O`f_%(EHXAKr7clatTGeaY4_&`C8E&VEIEHJ)UB-5ipqTW;Gh zv3hu`_c?)JBB_ls2+v8t$Mqg>*$zZJ~^;sp&V|2 z>ehN~=`yiSc(uwVrQosF}fg_kg80T>yoydH6n0kLg?W7=A6#x zO?vff6G#vQ)MF*82$bUB+MwGF9(}N;J}bv&*Y%~AOpVAprNSkY4H=*MUM#(O5*j5j1Wqj&x>t2RsaPZuKk+1@0>m8I+%O%){$wku-bymwE*#DWY%-Mzc+%gEQu%fB?D zMbT{7@al=sWY=dqqNAry{=N}5Lxx=ViMQ{KNBt0X6$v{r=9HW++?62R(BGsJ*Cvq@ zBb^qBv!il0`KN4H|A(H<)N6a-&}FqJaR&NLSUft$eNP$|z`3O6=5F@sGK>K*8f$)Z z2;qgGAF)V56T^ZLuH_aL23TArUXIYv0=~>``{}D1b&|QdM{|3+w$-z_cw@4q{gVhX z9p?@jFra3|kGsn!V-KD0lB3IJ!VQ-$(?VRvC)qzcG`{U;MHX*yH=V88g>H#SO>15u z`G3;sb$0T8Tyb-xw)sNIt)XUV*jkn*wzzl#i?SFc-qoa@{h#@RXp|=6` zlc>mQCez&9tjaw%apLtcP+*pbp%h)cdX*AYc(Hz@1oJV>GtF3~AHia*o016KDRbs% zfF=)H8M3^>nn&IW+D)rMp_do{#4(H~b?b@|1fJvIvbU}K?QgSdF~|_r=ej|)2KDQk zBaslJ#B+w_p8lnV50h)5N*ft{g;eRB7En}DV(01+*5>Z6{)5l~H|!?pt}BKY6Q^z1 z;4ZoMroWyXVq`~V3tNk0s2T*>g9dwkS}`KPl%pI02ge)@{Bm#n|3D%MU=+6j4#gok z4LR9IHQF)T>ZPhub(WHet*wlceEjGdz0vxo%lIyY*eFqFHmpvAB`Ynx)3g>F$0R=Oz4$1^~DKi%2>_%!Q$kmSqE!@KkrX(Q&rZa(W+>kJX4I zP>)S0Rlcxa^%ta2I4{@_B^rf!=06ASOrSp9%?U)vr~^#I zfuY@>;OeIaU9~Jvf9AnySow3z*OJ+1T10BF0)_y9e``SgGKzfH^Y%>TQDRIG%yF8n zvz^8y?q!S=XEdBzOVy?qVm0v}s)DjYBIrmvK{xJZ&@8fD&pA&q>}r30&*vUuxrYOg z68G2ZB?ATQyt_WsQqw6RvO|qST}IO80J;7a0AyW~-oV-zb7F>;xIK%n7U28Ys+Yi= zAwBtJHHRw&A9o)(&^GvxUcXH6DXoT71DH=Sr@={VDIPlO+fvBI(4|KxNy2;lSi-iq z@p&Tm`>+u3YaU*AAH1j1j#sY0P41c`lh5Bjx>Zrf=DbmVm?sHe zgf}+0bKP>ln~Qi4v^F%S8IZ6$yeo~d*-cN*VW|I|_UOeW;8G}D)&X=!3@i%7iLfmvDWXMSd+y0({wuE3r?U7|I!kr}AG`m}0v{yYeY z77~hr$werNvRi((clj$MTblzIS5q)26!*(ihj@b$xbar~>b7l7G23*_v6se5%AVep z1rO;@-{m3UOOFr9jBQgHa|%lZyqnZwRQS9jz&B`?DIrSj+PBA}ZN|dj*mL#pxOLXl zkqUvO%@YDv6vm8Brh4%Z$ke!NtT0t@yCfRY>u!Ezwl0p!UNy8wsw+nQB$&-=PFe^0 z1Fv=?bhMoax5-2u@vZR0FaFGli9_H#nPa$JEh|%Q1qn7lUn| z=~a_^cfdknj#Q%kR)N5Mt&v)XmIi7%xf`*1>Te&?T8S^N$I8KRa}9YFhjI}4uW8&= z{HkuK^#Wn2`BjW>LIFtoFzZnlCZXKm?IwiQQpiy$2YWu9H|ukSfGef+uLBDS016gN z926uBH-rXQIRx4aU%R?Iet&sAQ}3m0ZS z{ZcJ~i8EH05Ud=7Kn;m-Y8}3Mc6A=X{{}jfaJz_ySW{Cob;ux;-98gqD{+0rBwT*i z@7}#8244nBf)5$YM?O4XS@BEqL`9)y4p}`u$p1O}sMtQdHD8@3>Kc1qHn-3X;jL#^ zB8(NaKBUHiwZH+lAt}eqGm&nZKZ8%Ju=9}Z80e&HbRUxwP>5af8iQz&n>V9%Ynx~a zs$Q29D18c_f9tvpnpu^?+d|M!X8K+t#%V8lHA|kj2}Xy8L}s~!9wKf8R(NR@Irc~o zumg0F29T2i1_Z9PE_kkK?@9h-s>Uwveqke4?LQ2uNaE;X_9I71Wr3(-YG1~M&wiEG ztN!ZS21@^bRFT9dEOj=EyvSH>KD;;+){?&oJD>OdeO(GrdO_N>y&!J{gR7fTXWI4Fe6(dk7cHIp{@=t6wTr`4J ztI|+#AkUx7ZFDMMJCMq^J0>OoWH0P*PTkQc(Q>N*mOMeWX!X$jU9DDfx$?aMae)U& z#%4UJtHDEQ^O(6q4-iDm{&O-sBpAog&=us5w)lQtUwcc7Fdcdk$hJ-z+3^; z!nsxpy5-&dF0}$deoKfYlMBXS9afPuhiI{`BuV6?I4hs6$*&@%)+o3adTVi)($Lu0 zmWi*1)4p=9eZE|QEvE;{(QcS@!Y3~#r5Hh`7WZ-3$?fFk6DR5{NBPN(DH{tfB1}5z zMAb&ql7Gz!WD$sg&rfBQrhX$yF~A-N+nZV5OA9ms)_~U5A8qy9Y|#h*1K#U*>{u=H zDVXQL_9YPt>++eF58JkH|29Hb76N4_?dj9=R)G=vj*cSf)^D<3)dFGoJL_|6%)S#R zPl`EMP%UQvvg}+%CZ`gqjLZb*!yGO`k?&ge1S)f{S=kdhN^w4*f-LMkkvdOouDnuI zK7luIBYz7ugw>vOsL5?9{RF_!VKI*^+8n-4VZ#dwYN)HP>G-Dd?(&Ki;?4rLlxy!g z9kg43gG=SlMr_pFzkUl&X3I;@Lk_77U%)&ysePMq1-Pbi?LLv6Q2IF-r~Zvsx_1}Q z{0FZjJ=tD6b}g)){s`rdg8XuSIUCcmPV{>7TdPGG@i|S!AoBTnm~%p-!Ly z(;}X!WqX;-TSfjuK59yy=|*P{v_3BM3R?cVpk9_C z6UvZR)0UCyY{zRDa*on3f~}>ug^rPsoacTe9SAlN;h1B9axo$F)=glb=g+d40$usJ zSeDRY#4Rir0}K)4m1elw2()RwHXuVNvI5qMaL2$F!A3N2d=Hu3rMqt2XF>a1y?U3& z(WO=JfMrG@{?MT-7?47tWwYvCpIlf{(u($uDJ%*97t56x#wFR~O?jVWWQ41Z%VxUN zd`&4=`14;~ZI$|T){VAJ!T_C3^5VX(8VF2&zNkRmdcXh+47$u5ODSOASft%)qscoItj`H- zO?p9WY^+eWxCbW@9U>AbJ)O*k9JuNM+7g$gJm z-!Qh8^c<`n8Oddzh@n#UD(eHsp5<9b2Zw4B<;;BA+?4VjvYyZC-N9w0!~I38xvEmV z<KFQ0!{<`8bBS`b|4C(=K4`Gm+Ykt0YHs;tARhf$A3Jw*?0Ly*p z&7oZf+rkP`&LBvL7|4w&?rsrUyfoJM?THI7zP^ZdDLKC*!^!vTw*99(eU@D)J(&@u zGT=%^>(&kp)cYJsG`Sf3NnBvsT-2npt_KX2;Bz$i)THS4XVlzQ$FDjl zTQ0$2H14uQ_H);y%+mfbmPEL>XCI|;u6@AOn8$_K8y;gmEmxeI6xY?5tf>fzA_()Q37#)tC5rH zVk*5@Ae@(eaa!G?UsEyo8mU@<81O+%)$a5-;UrjhH{^~W!*1PVhyi+Ni+cy|T-)e( z(Aos)i z=-E+^+>SE(P!e%=FX3j;Zc_7T)iJrue{wgXn`hdrlf#p=qP$ymEZT4MIcZJe(&}qZ zFY06T+xyh&caz___m16U>n}HFAT7xTA#QZdLkkfC6}-BWKB;Y*goSlMco8OqsgL|_ zZk2~lJ&*lrYasWqh&v9u^X>k@`G5RRhtqUxY&m<@lwI~${vzGD3#@1_oxlm0`RhX= z|61BlkQQEn4MRL}eNP}@4<2gsM}+@koy_z0-gxuu&s!kBwoPo5 zX!)yL5}n8N!FDN8KS-%tmujxi)NexnCr+C$_s5Ro@L)`81t*Ie-k=GgX*VgDlEZ~s z0qo-}8rO0C);Nm^-FIY!o5VVMYwMWk4hwZHL>AiHd_tp&4-%N+ebg7b& z(SD61FNmME>K+4Z5`2;RqV71FKpVr0tfxK6$)k)*^yAtIvjN{D042s=1=0Pmm3~l} z+#Dh#4QC<+zNd`v3lM#FZuA`OKt(G0AL1!qGLZnqrU zRTo^K=1T*W@VnJDzt2mbwVds|XP!^hcPrE6B z90Xm@Zw2mC@wt-fw$GR#P1Pq9oU*bqgAp%JcY5);U(t%|mdhs-!9!6O1BmoPYxWx9 zu;5&(iSt5M`10Q$YpKsR*mL^q-5j%`{Y#rqxMsKtMVlcAH9m=oQuU@Q*Kyc6bgu2W z|NPRTTNyf6E*1}+eyqdVjLHsk9(Bt&G`TP#dj2Ejv*UW6oSN0B^vRIXv-gzO>$mib ztI>@j(>-n$N4?El?9R^BQ!jOE^rbSW*?RXuE0bGZ!@EK>t60Xq|NeZJAGjKJ=Wv?- zh4dax;`e_p3p&5!{`PI#B!83>Mh*@-R2crhOxs)bk|`~eCYhc@y1B+uIHM7+sc#`Z zaT5L3;vM=Q4^0yMz|F zj}I|uF|erAoBChW!{=hp`;Jj68J)ujBG@hH@J7 zJJV>=?)voFG1Kn#%wM^^O@?N#*qfg)cA@jYg`d3#Wq(S)@?_c0jFP##lCpd3ihpQ2 z*W=gnXIJ*lfc?jYP+QT<>$Mu5quy%;2I);`{6WwX5!dUw@3(dcOH7I_Y{Uts zw()D5;XMzl7PZBjD;6Gr=@PS+a&J?Wy>gXi_|KHeU;QCXYB3TZv(cc>Yd$tX*VRD( zOq|5PRKXm);cyL8qD06A1&c~g=5}Uc<#1Z09oR7h)oU36*oUo(8er^}3;?+=Ovc0y zr@dSq@7`;cOTCjj-fepJWXsvb!zY}Nep8fi>}dSWJEiYCjA-yGrCp-$qD3&q)loet zt1nFrq-4#Tl4_)M^6tP!0~{at{;F)Wd19xI9?la6`ppgd<#|3)d;6?ptL(Dq{Tp5_ zhVGgv$HkM6Ukq3@NAAIs`vEy^^XL~PA`~|Lv_|5Ji#rPj z41KZd+Jw2AbDVw^&l&%yy;XMKe&s`~57~{vv7Qfjzee=JT72blml+6oLg;|AnJ=z& z_l@Mf9Vj6ZwC?z{p->>SU1vI-KEm+gtRA^8`9ID3jh*)9TimlwE&DF&Ov|wj$GQ&h zMBC+JH_4O{a}so6IF9L%l6fkTGdWu%)gIbW?jnP~_0rLnLf@-fUcEqt_jS$pOB`}~ zr!`;X`TJ3_uj%l1#eojlOD^cWyKJ9*?8yt8DaUnU_svb29b2)!BG;+U?E6m5CY?KS zZrjCkU&@qEPQ5&8_>=JqOC6v7irqP6@^KB*BlVKcdbmY@^Y}H>H0Ak*9$8<@^=^D# z=yGxVl{F>G}~1gDR@ZN@C1V67ISjKh*Dx^2?uF z>g5c3c;c_a7p=}c8P(%fVRO61{eH-EY`CEVGOft33~ejJlF2DUp5AGVRo;72)_P?1 zqlr8HY(SXhcj>i>{j%w+n%wi7+CzgHw#Vig*vitzYV|RtvV3^{txcP#^^(Wca@lu1 zB%kXr*=qgDpV#X-lzou1E@D*W==Gq@B=Rc|;)JJ= zJbmmx`%SPl)l^qk-*Hv9)6c~Bt?g!SWU5E};>;VZpcS)S^5{a*hHqs*51qPIyzcXP z_AVCi)+22{T{t@Pe(NO|*~KLURJqBsy1o&ctz-}UiO&lR4_D3AlLOgWxs9WxeX|~o zd`ov7+dRGBqqP~s+u!_^eCyoK3iF5edpxPQ(aQH>ZuTbC(Njvt#JE{hoGfkRYqL6X z%5s|rYYp{XW*_Y&Ha5T{JeFLMBRvGX^l1${gRy;I|I8X@pk+1Jte)rnTTgro=`cwi zy8LF>^0kul1B8$|(QRLGu{%jA1(+URb<^$Dio#*@k;mj}%dg|QtPr~rZ z^+j-y^K}OA;=rmQk$oSy#v~u0H6he0Y>2?YW^>O6NQO7?NVfgo-*lkb_n_U+pSCYJ zTmMwtoDZHCbb>BieCIXx8Q;!!_{qu`H{H^?rVW)t-f4GVd~DZ~uY1~8#^>Ju`k>;w z&WvkG?bm0&=}>pJ!w49N2sQ(d4%s5F{M(B`OPBV`bv2ptV@p9obem7#oSE?!D+p}G z1TOG_QI85Q=!OfL_epTZU#9iX=oS@>ij3Ry4-(N4JO?r;wLc^C=h8n#)dD!`VQMcIF zu3pEJdJeyF%%W$bGik}uU%h+xi{9_mY=+Ckxc#@{l85;1*&j7mvA`5{A%W#Z|OQcSwC~b-TU|3y6>F3<;0V2p6~yl z))!x1_cfk#G2=+M$D3zMJ0;Dm*RQwoqvW2Rr77p!4kQ+M=uST8@+i5L!><8PJxVK+ zcMXd)Tdo+x{a0`#ov`w`!rAs(^1ZW>XPA49V~cKoc{Sl$Yh};(M`!NI&zP8han++` zt!Mp8DKBC(U52*t%uiR9psbYNpX%UqFwSXw7QcQIV0c7H=T|G^)_OSH((ktrmVg+4 z>%+@?wYJs*eMl=T#DMse!aJp$Di1vT^YO$xxz9`=JzpH5gd-Af8%=-wiwAlgWIzkM zW**nU(X-=SoUb!tozKaXC(k{8<>q|35LNq|MWg7&wU@it2meFd*w=YPRh=X+e=IG9}GC1JF!pc;iYBMTo&ePn07jnI5WP( zhUbOu{f|A%optwA>E=f{i@lwVW*zf!^Ci}sQXA1)lHuvh+JNL^J z=N>Os%`&UkqtfqqhpfIGF}{4{#>3RCENz^T+}4uLm9lZk%aTPMkxV-p3+asvd?&Q~ z*?as5jpn@+RR+>^kanIr8hX}hOqwuA!0tZq;z8#2WflvUs(XGuI(GkwjL&c~mxX>L zx(-j&x017Q7I<2ui9ipL=#?o`r+VsWd*rv!)EcDqQxUtK0l3d!HukNG945XZ4^l1= zxi9ynKu7C=>feKOv$~d@&}-5rzC*oFJxv?(Z~HO({$2G4|Je##jf4 zdr3Gps4AfXxEF!&%v~i()+9?`!E@ls3?C4uY}}K&*Pxk@Maxb8bkj`^P`18kBj!1+ZB<>nwWZUz?pLa39!KY56QrDiqr zz1MD}TFl-Wk&=1TJnlfL?b(dV_;R1@98Hsc7Q0Tp!oVXVLiAuOFqX>+3zv5|P1|n7 zZ1e0c>FQ3|z8AkPw|x)q=Y~Xd8eIo3SC!KvK7O9grZM=218CFnu%6bKY98x#u1v&p z+FRkw$w}}>L6^?g`x8ud0kHlW9ujq$aBfkWue1KCaN`ho%8=&_`Q{U`elI771}a?0 z80KO*fI#$e)7N3E;`OJC&7*(i=ZEaC*YjZf>Dql_H{H+q5Eq+YT3miO`FP@&u*ds$ zE>oU(rTx2~11C)QG{TU;em5bXMGHWj+zK?5#;Bl;UYNrE=}Xh=saF3yoI~fbepnw% zQ`~#g!58#{LGu!7ia6{zLvNMURb4-$#;nlC#qMTVUeHnE&4oUZ4+n+BsO5Z}QKzs^ z%dt6M=c@m}Hw%iIFxC#RsG$If4#ZG-O-sx2@yJo5u7W8@oCx0R?57G9{GB_BFo2}` z%$R=w(-VV7i%`7f^0wb#X70-X>x4HWV>Ncq9#(5Gux>YA*pi4bC3CJn{d(WK;(bQi z+LeQUYkhGZowj+U-T5NhO6#X(`T3>qx)yfam+^kpxM6dXtsclVwQzb8W`fW8#^1%G z1~Y$E9EgfuDPa5Lk; z^wLq*)84aZk6fP%#eP4+I_P>ll$zX*3>n+uV)@tclJdl~z=Tl4o??FE#v!aW;_||H zca6xpI*^cutxAT)9a{R27oaC&CDt&mlG6?!5PYDzQ9}OE(c#wl>%AWjH!^nEf6DsM zk^MO#4`&T>DOm3V@{v?PxfN5wQh_e=#d_>}fYR6ZsvlOzT_v1%W+#rr$ddh}`B&awO&cd8)^e3n4de4u&b1|Bh;M`MmFEeDiYmr?B)BLgPM2_z@0; z!)Xz{SxOTAlIv=7MOdxo%~vx(J0FVCTG#|(VI>q5I#sPsojQ04Hzd^b*@H{9PQ&)8 z$gz^*EyiOcWgct;V6XJPNRfFgOg_mp`yeK%kI8oaiPOr138o(W{B|!?H2AsRMyh5fml3jbGO5*Dtyx zY05B6kTNwbH~3y&YF&%k=_shxhz?J>|_zS&^+BDE3O4Fqv(HAhN~?A*sYHXt^ntAo>Ab zUdK;d)@zOvUR)Dm&XZr{vbOkx2h*uzm<0l1THv!Si#^qKOzVpUiA!yLg>VjbcI3aB(lYxUR>G?CpYwz5v5bYxG_V?d_RkP z<>B!v9>|_s2=3z6T#0Xy^g-+@a1RRf3cYsi>c}KCD@*d7f)6)zBw|2BYQk&e?lRa7 zmijf}FS7#ZJ%oF}BrzHLGL^aNo_C7nVXF?KB+j`z$-O|4DYkl=#}#pEeEgB4&{GOk!jx zWR+qVgmx0F*L8%Qio2v<604Ypg+U&jWG2(969K4>b2m+BHJGQHLuT4#EyS2De$D4g zzfHtCpn?B}$qHo=%(zQb(tFr3sd$f1Gp-k^QFGT_##w&{;4_ko|2Ul_5kc~WeTp3= zic4CHfekRHf0H<0#!948H0v?TA8|z1KiM~W_^9O0Z>U~|n@_S3^ARWl&2?qwRsalx z9vCddA1T-Ei697-4tq9Fr(>j+Nc^_8muNY}y)Ti*l3~bzD}PcFdH{dagF4jjzf31s z`dRaLa;C`=6NOnMbVdU$@rLBa+=v4vivER}Q>M}wJmIf3s#o5}mMUh!AhqZUa)Ax& zM=oT`b=7L}0M9DtUSon%C02nv&9-evDPQ<>vz>TWD$0L(e#o=na5SEBQto(>V-lf6 zv^0dR4>#K#nWxiGFDUE_|4UwvtXt2*dwNnSx_6H%N$MqY>O5jC1~SE>#y9Te(U1DEc~`L?8$?#m1kGkWuHB>;PdODB8}s+WUmW${JW*qu$(EvytCpCLT&$-Xj z|3-x}D#X1e{u~u3rXTTaVhxZ?7?eBBbE`Qs@n=uQ-o?Q9*7|$?A5~`pmUG^|{hJiB z6_uSzqOxWgWT{k?L>pyI%8;FeFrr0DDhZ)fL}iIA5s@VdLs3ljUC0uVz5nOBnR(u~ z<2jE1`_43V_xpXn*K(fcbzarC3GRZD{DNW~%Y9`efFn$MBoPmKf*Be?G32gF$f2kb z%HWe@4Q3yqm_3-V7TEysgYYeUw?2>p1%dEx%)F6e4gLBeOpuq)OkkhBZJ1#}&;%#n zNXB*rM#;`zdG+~YCauShHCwpvQmGtedrd{d#4J_x9$V4M|E@J)EJwgF1`3LGfgM zld!czP)9?4?1>Lo%#Jc8$fc9@BaJYod-%o~C6SDMK{yN)%ORo5={l$soVn5(ty@RH zSbKnjn2vpYa9OV{pGs!lI(6f(F<^QLA%9PQIoZB33CM+TltwgCJ-Vh(dRYZNDNXQiXS4U}SEa*;qAPyno1UxS8` z5+UGKH`_m0p)OFJj25GflJ9{jlyMRMLjj{Wd0WpP<$%KV$;0F32gCFK_4#3KlyhP6 ztTz>>G1&ks=aMpu$SC9STxz-I=H?1SWU2NQig_@)GFXJ9XVbuC{Y1ry)lL&|R2j*E zx|65MZ^Nzt2n6Xvu^sEGfzT7!_>n9I<3sb zR6FCt^?A(~ge(bJJYe4?li-IvuC8d*^YV%3CkGFf0dzWD*9Uu(!jR#}rV7ldw1{b} z>ut2Po)G##$oQmXUFb4?D~}EIs~ysF+>5Pc2MV^P;2ZmE&Tde2aN4~SeS5ZO(718q zIcRlQTG|5B4zk(Cc*DQxwR!a`V0o27E}Fy6o=f7W4<8|kDZ77a(ATQBk+|M&`umfL z*HUJNE%B%vId0qzoCyv7*kigzbVQ8u% z-mZ)hNp0GG*oH*v(|@vNZ!7P#T?Q_REn*fU3!JHq&XEhxYg@HRqC$|u2qPLveKF0{ z78e^^7_2hd+t8QE>B={ETkVzkCZQNSmA~_6S2US02GQl zA<dbBJ5Jcy!Nwi5Cs{}CGdOIMcc;C@t~wh71cM;&Cd zhPilxk=TvSb*q`CZyq=J?LR%3F^d8TH1G@%%7U0^xv%&0ao>GN8%V zB+%;MZ-BsgjLY6JuHY1_srtoQDkm}~A)$*-mvJ32@N7^0A56HEUjnMogmR(Lk4+4L z)(|wdVB{aqXESo$IpM=B4cp3|69-McGqJOgktTSWCVM;|1vj0bL3P#p#kc+;{F&W} zhFok4lZy9{S6gBPI(gDF5j|kSDfLHPlE6Yor#~qzx;kVBABHJ~%5;|gu9~T#w zIX`sh2o@VO<{Ywa!){I6K@$i$7adH);NQckdFxQ&b|+<%Z1l|vW-zv-{3i_L$9!ph zrB&N4ig*7E${a8=#;E80n7BA25QAWdh_``gxS}mKRhk$60QNHBYMo=+CkV?Td508N zIyh=AdJ=Qbt3U6~lL(#6n6o^51Sp|+3*fI%Yi`w>@uiDL>^*wajkstn`sQR@Hfsh< zEzL~X)Msuo;;O`Zr*tQrTx3y;9@tD* z*5d5`b_+k>FKH(~$sbM**T~5EbW7!I69QevyNn+(YAfF?q_n7b962bghKgDpoOyUd zR)Fhy)ZKZ!v5zOOz?+K#usa4#j>r9G*1*AIQ7G9zj6W@mlKS~ETbCMi7w72F@&Mft z$FEZ8`rO>tSrTsVS$8@zE%b5V4St&ZRBL{EFgJ_|1X<%G`{}i)8kRn~Fkd$`!RnKF z;Q)7c_eYc?O^~LYxo}|!xN3gKo0E8j4B9_i zt(x8k8vyO$n|o?fZ8U*u&75D~m}TiK5h!i$#C;B@q;){dQ;&t+(l?jdUVRP1%NWiu z{;B-iwSzJe9+10|c|Yq`^Iy<>Wb zGrXwON^Pf1qk5N@{QbkW>huCwB6hRLHp#g!uC*_f9j7j~oBrn9u=z2Mhh;T% zXeg`5o6w3e%xpzpoOJEv`?FeZ7oX>_ZJG*nh#Xrnh*l`q%hT;>;-a@C-PIHEm(hB= zlvy9w6KBGa$4S@F;>)PQ$4o7RBLfU&G~i)bSw}@Eb#pkT7vU7@Ig#^810tO)N^|aT zx9}{)kRH5v2kOW*i|V!M+P%A@g7d98qSqRNaBF;Ay+7!b{dxeHPeq^CdTSV-1`f;M$LKN+m+lxZE?cv0ix{73SjVIG@BJT9B zK4C)ifD6)AZkgiosVa)dUER?~@p}`icE5bvpgr~)brkyDyH_lpb#L-q-TV`A7dbI_ zg^Cl5Tx{{Pi=CCXl^NmG9QmlZ!kP!=)h%P=k#)}ho_CPbWb3; z?NB|QLs;t7p}C8L!&-R_gTB8DEZ0giKI>yKPP?o$zRz4sB(!0AgG1&7gymnR0CTT= zb#nysJgX&Iksvrn*1Jo>n1!)sls*h&iMXfrOotaRLKnmcl{id!?b4{L_jBoqTO6vM zGyWOLviS*q4SB+@`s#WK%O)4|;}r_x>W@9E7R@3cLTialm?$afq-9Z|jD>@015oZb z?5ak&quiJSPR5j<2CREsGkNxqFh=jaPl>7p-Z; z;5L1q2eK$0;~$^GbAQlf0nFxOg zi?#|QLGy{u?;keg$qW+Zy*M3_DptkE-~Dj!$*M8H^I(~trr$7*SiCu7qV?U0+Lj*p z&u;2Dt+BKdnDWV*2`0;Iawbf^jZj@Ibht(`FD>IC%4+43S8FzhQLD(53-FaJlP|UP zG5}r`{1eI~0MfS=w0_cr>ia!9h}?PX?3`f!FY9>S{nolz){$M~(&&jREjweAX+$y) zR?efjl~zI)6Nz~pVC1Om`6d5IlTL5qiTRI+p}e1K6gjg2Ok0Qt#7|+KRUt9l?iVGVWoz z=Xspry2F-*+sEbjyUGd$20NtuVx5g_XBL~qi3K0E0P?JzoYqmeDJw7aU`xI)lqfd# z`|kLwTl==-`M2-4@XemFno}O+t{8Dx|1!c?tEEd%G#j||=&W#KaJGtq4%NE9 zGo`Gfqi|+juDe`uyzfNcL^U3^>(;8T)Q+C_PAooi_3DVKV?bqDZb#=N(Inpd)`vIe z3A@VZ@yM)s8!|F7K&*}cVRIL$|YmM#mkqq#F&#_GMUgRflfY{d_X?vOZQoioFA)OJo~$NRGsXJ z78WZ$LyWiQVj0SsElL8D^6UmL;6Ej=D8v-t5uYJ5=CaMKS^IE23033{iv1pm*c6Za zP36v4riu`q_|Vnt?2b*>eJrXn)QefHB=s90;>=GbUit4uc*0_giu=_+NBgO34hW=x z>uVa^D0J1B{kkseHqB+Ze;l z5B66WsUui~qoNabkEW8b!y$w-)>Ppzkg#YCAQyrR8GK_voHr-qumnW{jsUmQr@vA^ z+AH<~$6tDDevGWo0-+tuz7d?lnWx!xGrc$6I#5JyQQPy&@XXv!wF=*4LF~h4-D5*W zdJdgDaFYCc+4#bt6RW^Pr!@Ze4%h6L3${|b)E>17+vg#4RQzKNr~?G|Wec`ae97t} zx*wTwkZqU(bfT=o5}F$j5*u6c;f`0hEAH(~=8C?D8DlUv3pC7Z-m1kmEy}W2IcF}A zqI{qKO$-laqkw@)9JTi;%0&Ax9#9_Y@0EXFW?Yi%{B>>pE@gW%?=T(1~p!( zd+ZG|pD3WkjhbMaIX{0T&GaO?jiJ~`i+vw$#3i=3vdTL3TEkj*-%`rT)UgmyV1pnB zllf-B-ZuB1X>2wk9Zxmc^G6)E{$+k3X68&ehc;?FFc|WiN=M|uk}PFBA1T0HkH{@s zwoJIt7r}y@nAWWu>>U+Oa({VbyFW_9HAfb#J!UrdQP7(Ye&`fr=L=6qR+n?-Q*P?G zQ$Imi6wZ9Lfo0v4aV!sM*R$uLYXjbSrcT-_m^~Pa7_4KQ!D8qZf6S8opD9kOIdrcM zFPJQYzvZRdTlPPeRT9TdB}cuscw;2a zz8h7tE<5ly!}ltWvAbWnn@l^&%fVn& z>gANDbI(=JT>PnMNZTYBFF=Q>g^4xTDIsrKmnzdwKW;VgUSK1juk>;)|Aq+Xt?)(> z)ROd6aHYE~Q;NjDf%Q3Tu|L0!!AX6mLwp#@phW6^Tp*j%Vz*s%s@z6jzf_Vp ziHh3ilEdO;IZ|lPGY+Zb@ARVZ{0zhUj;?-iic`TAy?VMqxq`Qgpa^RO`ra7jM)KJ8 z*7a-MZ5O0uia;HOu%e|byK}6ETB9~={(#Z8{{G-6Up#pE6$8 zpxyn(*X5=oKo-YUSOP1C#K(;vFKgr3pupa|vR*;+U}o;>-sFBV;-tdjsb{-RQ${-VaT^{` z?o$rM%sRZ2!y?-hvtGtzWo1pcP;lweU?3gpKB=sz;FEx!SU!nuyMIQQcWTm(u-p~8 zAEr2{SmbUC^dt12CU?vRp%x*65ah$BXdmLL>oO!HxDP2Ng4Q4j0|tfciIHSQH5xn4 z_L;;hYG7_ct7p9?3q8Q)6HRWZk>TI#N7eKHC*Az}-GtDxBJsUAaiV`|^TndOm$I7 zvsJ?qGSzEW^Aa+-SQ!`Zac}ZpReq|Vzs1;6y2Z)#WwPf022W_G7cbIo`=?V>`?u~u zqR-mvM&(146dS$paSv(M$4b=Z(vq`$Y#Nir)&zi}AT1yZhdD^7>Z`pvo3; zyDaStjbzJ^dE#o$O&;Lu%Inv^HUeH%*dMtd-MeeD*EKfYDz=!8KnyTMnZ)tms9YW# zyETtMoq_BCN={a?7rT!B3r9eT*p>_Ow-YppQ#R!5i3i4>rr?Xh)ZtejBtEUMXW1oF z8HE4X;&L`L8pl^$T4?b`nIC&Gtt4F=#lBSIIbD|1v)tX_iPqbkPcBQPe@$WLdk%{H zy6B&7S9WKdOds3#*}a(7BbZx@0CO5l^ylN#Sh4LUe%AB@D4N|fq!||-g@C8j65F2d zj2i$KfDE%XxRn3woCSafcSm{9&swm_moYpA(Ho~g{-jq6wvw-3j#_z(*0x8Z_66)| z>?JfHy;Y`jS@T}A@3jKuTl(m!eZ@~7hPg#yDNU)7oD92^Gq|H4U018Q752ZROyN)I z0xn+BOYcSpf$sX$&#$}R%w&ek+~2<+S?N>OwgX^(IH}mMVzvIf9{@f=iC)(`)819&T|77aetS*A~m*N0! zSw}>R62-8yJT#^=mw+8$s~Jg^ITSkZnD}WokXIzNtl19;e`|caNGhnoDUr9R%)R>H zUN;B0LFrgYw*ub$(TXhJA?L^`oU`Dp&1Axru`NUuZ1WqRWjdTeypOluM!9oXOT=9XdRKUtrr(U;I>(HI&y+3GHo!Sg0bA@({Xiba>Y+$$GrJ-=bpyZ z1v~#PX2C-@6Aw?Y0EKu*7x3`@z3LldXNwjK=&A9`pIwM*#B!l2-i9~PjJ5{nSmBf= zpr=ga1hJ!hmev$n)oJuT)24iQ2+UJ&KEP(G^Oq4WIIM~E=1V4bp%ej+*81l$$1ti;0A^&A)o@Rq98rV~22Vm>N$inySIk`5oo6 zGltV&fAoL)S&XF^GQNBB8R2ItdcIk%yGV!gj@z2nJ8{ZqoH)R79=!jITK%FhNoB&4 z*S$o7o#`C9;~2vj(i&Tb>&QZ>H8Upva%ae5%*S$BF|k4xwEudfE9H^OX$M~#%wM$e z%MlOo_3W8>c=?P>vC|edfi6oT2Q{>Jhs|raZk{;F%Oi(60bMU-DWe2{o;_XOYELiw z5>Ko6M=M{LVLG+eYTf$TuWw{gF=z`UWKUwP`c?^!-27xS}%^4~35Ub09S zYINKlaB?ZLtYrrg%-VONIY!--KT~|@u!Ii8`M!yi)xRF&8F`HIUCc=3K^}amr&dEj zqLVI%5G$o5VF?()jKSi$&?0`bQ9^ z7a`6fAEhoV3vsSo=IV-VHFvx|1t>0;0&tNNWOdV+tXUDpuIbIbY}j;!cO=yCXa3%~ z2#5qJBcM`)P(iUe>L5k;!Z%xI)p>hEutM6bpm~^z}z20}$GwpJ3Vy^_$jiT-l zsv9gNsp_4cW^~H15hI3hQt-1o_i&4y+)SKj+sbNNX}<-yYd)0Ehvm=;f`D|IT~EAQ zS#Dt3gG!p{Xl`W{RIsPMFi#tTiGkR4)h2~lLS+daVYbTNonJ-m z;B&1VFD_oadUNK)!+=?^jxu&?m(rLzqqUh|@pSE7a3dbvJZTK!dQ1}U^jEeE->PI= zkJRP255=;N46=nyH7jhki@S$JP%W(;w|DLZPSGAY!lgS0>9gct?uetGnr3t};mo5HWsvFN!=gz)3a>Q=<@Vt6mPXxeva3V1( zn3%Cb$KPLUJ}8ceI-+X;MbhSGl+09pMvo3eQW|GvbNbtEE32=IDI;Z>pC}?~GpE2Qx}3 zZizPe4hQNG`>{sI?2%wcC&$k005+%@NO3euBTy`xboVtdiRN&CF9^$*3GgS!)r%p3U40Fl7mM(Gk?%m~9$?6y6 z9gUFokI&RVbmrUcq$}8OWI-Ck+RH{9jNp|JT|T;G+sf!IS&*p=aiCaJ4ZvJ zPksPEa1q5Yf(jBq6WPkd@ROK7fVKXPPjhwoo9r)wxXAMrI2eT>UX@5!1nsp;vE=ql zLVRa--2g^Nc~K%Fg1IR46TdD>Es7BeW*p=u_!&mKoH%8C6DdXjrY=-tmmKtxhlpV! zDs@raK}Xv9tu4L9I~BX}o9g|z=4Y5T#HnpU4eyYHIO^fPCRUdm;Mn-d*9iGv%w*q+ zeA!-D!EG^h7c?I=ia5OSuz?s#Z4J}l5#&+wnMp%mF8-DL?cLAx{%`{lI3;J%-Ok@_ zso&%<(8rqAW;!G^Q2yxn$s5p(;_oJAgd!=A%$Xsu0Jo74nj}<9ld0yddaGE1drioeTgx3t=yJm;iXDs-QEP2KoP>8%>w;EBea= z_D^cYMSxjca#-Xe@tAg}n@6sq)X2(8dmph$AU7@bU@3?A*XC%CDE17^g4;~y0V%~F zT_<)i%iHtu_3fr$28^mNedK+3OlN>UAqvzx3iho08g_o8AHTMFG*Q!Ldvv^ol|h45 zD>}t6?Tp=%*Pn$=M3OlBM1|U|tl3@7^2%TIs9)>*F-z1b8>6Q`L9n+Wo*4h@tBOU{ z+*(beSi2o5DGz~`iFT~(Uc*mA2_TZmQlrXdU^-_huf6_sTYs^?1|(3o`iMBOXU%lB zcVdD7IjFH&ApfC!b*fW)rM(Ml>C0>B2Nqy7g8snkPYv55Sv#MdJujAHli3j@OhvJ; zu~lW$*u}bKaHnTMI#$B?(G^dt{`mu!l?$N1-n)K3<>=rC=23O|liK;PN#G_Rc z8c_Ix%pRdTSh7s=By|ANT6xWrR)XpIL;>^En`6k>Qbbm`q4VDvwnKL*Mtq>hX74CJ^=J#Jspuw=DDYbi zf@xWZTuQE#7jKxyN*Wa2?MKI?2BAz4wZ7aBKEUI9Z$HN_2-a1ADOsePTy}Lj{zr=t zrwSwtWdn2j>uo37ttAKNmz2nMEIdRv#9Ml4$i_f~7b8#owTvI;gb!>IG3`$8H7rjR zfQk?@8O|ZoIlm6L(lPI5uKj-XOQfd7FC&LLIE1jc1QaG>q|Gw{{uu<3C=Rk--s<-; zOFu^%Oa`PrhR0+Jz-Te3Mh_U-w_G3JtAqmEtssfVWh; z8;^bsLN-xMWcDZ)uhJY*WC0utTRBv7ur|y9EeM%^N#tf zwdSSCJdDUul+2~PPFE)YKsHcJ7>8eTYU8@~>(^4iuMO=YPkz`(FsH{U8z-=Vnzh;K)ucD=*dr=aR`vduV!@VMUW#{pKgDBUnGh1$^kd(7y*WQ*x!RV9_iv@ zU^X~gf>7PxKi#FS+y>+Iki+oIfQlXEo{)|y*By7b~icmk)k#jSRz?RO>s+ySL}LI=(N9>q@8z>nWVlwHf%fvnNsG-`x^sa__x#$pm{#PMSK0HU2=p|UAd_^~ZOzviEMA zlSbS)I(M>kB(PE&XzA$I}jvaoIhp0kWI!`4z^; z>C6(PVC%6XeL_w@!G@86{&9b4%;4DHZ@JQ*DD_AHdccoMSGaB}FKHOTrl|JizQ^^V zfkypP$2HyM;SpoQm-l)fX!Vc&{K?a&hfCx4#Esa2K&t(oJ)bq|zsR7p6v)-nQy&0I z-)z;tFIJ;%gy~$~+Xa!|NoK8|Y8PuvXZYyIB(5?}-9nxvQptm(=@H4Hi-q&yW?#cH zFc)OWPc1G9C|z5WqoQS>ap$Pxf59)VIk~J4JQLrXulzflcbACgJE~Dhxp4#bWl!RO z?|Ja-+4&W^ne6#C-FoNFILK+KJLy&~%cOyb*O5cUN_R? z1Pb|ea()LO(;j@Bx!gxg^DdwZ;uANwmTXc>-v|hykmiB%S)!bkO)si2W#b!SEq@=( za}ZqrC5P@N{8k&YPc+UeSUtK=!%J6iGYT^qoca9qs}f;Q{zB7f^6Mz)SFwXBtHE}= z7xb^G6Hg7KXfT#*4rSSS>=CBo-1vJPQ$FIvG#REH@cve)X1i|O-&& z6RBe}=U+Y#L0<$~OVn)f^fM8LUVwOh%yI4P)jWFcSq(%a%0EN-a1A2}yI1H{I*&O- z#p!AX9*pqP7-EjIXG_W%$&yPdPY$|%`XPSAJLz6P7PuR0eE3At#h`W7HOrgP%FM66 z2(#(&IKC0{T1$W_N>)Xqvu57X-w#?pdC0?dPE$Be;VKp`Mn+odQcoj5-6++LEY9{V z3jmV`(1VQ9PhXFxZ76evt9Ku8O!1@G`u==S^=X2hNXSb2PT3C7wWQ;A-A#x+Rty8MsW`%~^{=pPV>a-|T_mM~U6wYtp%7jL!A7=I9!KTh+JqF{ zLsl8d4k2P$XuiRWPARHD_8#YD&E~O|>o}kytJ{tTV16Wdq7AcSP^}}Q1<2#$J zD2w|W3mF<1nuSJ5B|d1!0^!;&IvnV;-6n!zm936hfjv~g4$l%tg|qnoV@0!uwW2Lv z-#^tB9*QbkDsvo7ygO*tP{=wMG3MuqwXsWave;cB9={TbJ6*w4zY!5eAUER0VWuHu zK;2Kxy_=p@@WekscQ*H$u7(Ax`l(r&t;8Dy1}GS}#HNz*L|`UgaT-Lb?!lH7g@eB0 zyS*&^(x3vt?-_8BWo;Uk!l1UwO?>_-^~1O{7ZLi?$gRIIrR=R<<~S5~0+jS@5h2w} zc#{?_)N#R)*(DH~%=yN9VP?b+KC?%@WjsUn87JPW0|Adpy1Bc=2g^Lyq?@)IP@pfS zfwY0urW5>M0$fc;(!7Z!imV}3Z?S>f-yVPZmCCWEOouEtl1}L-m(h2ga;D%f`TaBEmJ;aRCtMwczvMdZJJ{h(z=Or=b4mDW}BCM`hpifyH` zGaCHsu2~tbRI!+HrKqSPY5DSX#C2>$iW57-5}KA(+qc1WzGY?6w~GKw z5rF96R@uzu-fMWaGthJJ=wq{AYJ)mTa=(3KZ}}R#y{K8Z0E7Mgv&*$IyK!2@8l12a zJnOD28~NyN&fdO#{LH?XO4-Q^Gd`)TFe%ojS3Ja>KIM;+g84V0C_iX2d>K-r!s)9& zT)u2Cgc`u20&Hj3ZO<3?RNis4Er4hh-)HVVz&D7*D?76E{YUl5KYGr6I}_Ub#r=eG{H0}>&v)bEf1>iXZ%&;DIDd}Op&eCE-!@Rc+tOx9 zabN%Hs&hYod~18`?|V7(?UP384jAy`!1K2Ump0NI;K0O!2LpfqrMEsA zkxYojw|?7!t$1=g6Z)2BIPlH7bF?D&LiNW*vTGX&b|i(D{6ryseo{9KD*T4r0B2|S zs=2b<9yT?7N%do%(PF|RZqvJ}nzZJ0C;~WyHFDcsE&6t<1M>(X{ZyEHc|B3N*^4be zOieuk0HKCoQvT&zr~8AgBApLT8IJTlW^Cui#B&!QMr6$GI(HuK7gowNi|oIVX#}(2 zN_IungwzJR$#+OvCF6qVf&{<%Ut+XjEqV_}d_;~OKR$SO$-s)tszGt(82>)F`Z_kC z!|Ydw3H;#nlemqF00ct~6e6J*G-n(g!U@z$GQHDgNq=fLS%QWXVA)i`JCrBvYh4B8 z?%vuV9opQqioGOi3!2UT`)^&Dc-QO?+3bKJl45y64@H~BYkw}teS}5jU=k3;^}d$I z*$eFzvVgWm|1aN{HA~2->`z)@hhS4?SS76_fBTN0@#vDOebmJ_sdO9G8nCLGwAlv~ z5j8`5oEcIpuLvtZW#2eB~iN|!C#mlOW{8jU3E6?oZ0fX-wX4ap1>(C0zqySI>#RJ|{ z_UWu|175Tu<_}V^hQ*@l2%6|u_Zt59N60iJMKx8AG_%Ro^O1)O5F=#K^luaVd-7)- z7Z?JygxK|v?K+#SQoc(OH#PqqhOE3!Q&8K0G5}F~7Qf;otGuhuGS9BQdT>m(uaR_$ z9P&Z$zZz$+zI^k?#A<-W7o$Eb9s^ip%7<8>(qFM38uwJ|w{xGrJ^OBH%5%qz2?Hqj z;%9hCHQ0khP4D$;BaO*dh(-@#yK(U_#mU6DRJJ-CTenOJJ)%!DSYKSysS^;wqxE zd`WeVUii1HIz9ZF6b(R8BNvq@A{GY#+5_JG>=1t{^6ZD$gjj$h;B^K}mCfDHNcLy& z9Vxff*C#|M`{)hvlSTo*%1DE>EQ~(_$YzRf6db{W?U4i5#n*grHRCqba9<6t^Nd2) zC(((dDbqROHX_3!&Q|&DtP#p$L;fh&ZX{MsE&wO-A$i~C_*#S#3WWeSRHQW(%$|O{ z*X2b9f}#2fxw~cG-ZrR3?KyPeG7eIs6Yon3hg((MS>p7TE+rSyUJ+re_Py#IAF3uT zI(hAbQ<{qytne?Sr6^iP4)E#_rTP`VPh1PXV?5zM`}U00KPw`aOXKyKv2*WT3I*1& z;;_OrD3Zt;-{{k$P_Bsey_t&DzRML`M)Z`RhK^|dPyTgpTlGB-hR`d z)t&09Z*3nOt2*+n>%zA`szT(S~1TbJz7aYc=1Z1t%HLNg(>?3x}xV1?o(W#OPi}9%L}5xmvv1S(D8KouU|F} z#Vse{W8f;BIusa69X`DhUTRQQg>lD@xlmlZ0@tHxL6W&QfT$sK005l_&wtzPqKSQa z4d9Zy0o^p+kH~B{E zaqVdv>}6Rh4g}fSHCN|nf-uZ#YGX)6QD629GLFd=(e=>UUAqD;xJ*2)}v+EPY+4kkt zKQTD?Uq^034FTi9It=qEQw({)L>MJ7MPH-WuH9gX2QMTs!hQj7O`ri5^XP℞+lE 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%0D$MhlZQ$OE+ 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 qRVdnx`dtxWV!!W)r6UkT`DMPyZhrX0L+) literal 151647 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 XYuEHstXlMwf5Fsf>ZIfev)BC}lALgV diff --git a/doc/software_architecture/buildcc_single_lib.PNG b/doc/software_architecture/buildcc_single_lib.PNG index 2f836e4a637cceddd7bca1c411757a90b8354283..9038de0b052dd5f2849f2f8a1221b5bf44c60b49 100644 GIT binary patch literal 128739 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 *yPIEH0 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 B0o4Ei literal 120571 zcmd43iC@p@_XgaU!3=|86h$>g(JCSlm93q$?+a2|v})1bFc?ckS}dh#-zk-LvZT_! z?@?(FEn2iZ*D1bZe$Vp)e+W z!!Irj3=5clUWA{pj~af#e-@pPlRCsOOaFvqN8V&$_=7>_(0-M(f&I;n8dak+GoS9h zblrbMr^2dW+1i&X2be0`6FTh+A4ff|I^4J>dAK+!)GwS(JI>(hZNrer3Kg3I`G2ll zzrFO_KSo=^(%TmB{Mk1()1AM5?IqP)D}F4^w{zrv^QOyn#hYK--xT)^oZNZ0cmW>c z-!GN3C6bH({g(c3^@w|u^Mj}R6~_PjHjDSaUHYGwtpDl%$8VA#Z1eWv z!>#<{^vEz&*iQ8&kuI}yhQ&$KWO^{Z?cc^%;$d1c#TH~o?lua zEJCLE?Tc%JdgzY~9viJ}Y?3A%v9K-fBmA*pzy0vvgWCh zz(+2Dfr0(k4FzPh9vj~%U-|9r@ZWvhisK7BPMB7NUG8kPu&`LP>H9^fGQt43HlHfJ zSDiaEDzJO^ZjAMH;NFuW@ z+>iC-<>l?L@7It~YRz%wlxcPQ63?Nz>C9+$aE=JoXrhOTzs?W0E!T+PGgHx?Ei8UM?=>B^aU z?$dTM6$aj-M#DA&SsxEP@>X2mSDP5XVb@*uY$(0y-S>uKwRdid{=RTQ#^;UEu$_C@ zEMtyZoW=$j|9G~p(qR35gVj95~UxVX4Hwja<6+Uuw! zFE8)Z>8JkKWx_^uc51jbC@sX``yGk71Vi<`5$ryrne9C0&*3^$u-PZfu*jdAlT*US z7S>5e?lV$5lCWp+$-z?b*{nB4$u$YOv5yS$-|x{=%;)lIGU$;1?Z@xl)yoray1Ei} zvUKl2SFpQ(Zf@>gQBh8rjgr@{b7ap<_L-K2{Dm{EdTgTX$tJ4hv%_WFs;Fyt=C+{W z6~mxBuN%U07R-EOAF?zTFJs}5p(Xg#Okz+jQhk_xPvwJKGE{a`ZgPXRG|wp5OWQ?FN~KOov1mkA1TUyX(jeqmn?) zj%`CmCS@V}b8fckBsCM5z%UCX|Zu|5Efb9|IdG8oWe6sPEKyTqA|@< z{p86o`+qm?(~hs>B&OB+`oVS zlAnK8@MaTLiB;ndO=K$k`M){s>AvXb=!Wz&k*Sug3Ekbs5>irqc^8((C`Wp^xVj2q z;S*oJ6t%YMBREcM>1%Hf-SZ(!*~izlb_T)*Rit!j?7oV85WC_*C;ooF5N8+cGjUN56P+C_N*iFh5`FhaY}$n(T>W zT)UQQ#R_jh{nqEt53;ebWqio_!XZOO<;A*(&oDVa&xyYCzkBzt;T4U2`#h$mrc@I3 zvIR@euao-k>bN%Ig=#n`L+zKWd+a-SRgT=+ij&wsG(4;vBx2Wp4}a&>+nSp@Irc$- z+kFE+3`F1M(*<}P_nI|pZXe#%Y@N^Q&wZ>@QTkv3LfOA2ht$^d`o>0o6HT%xEXT0u z1@^f(SX>_q85$b$Nls2Kw@z$-_wG-2cJ_(!apT^qXrHjk$fIVkApgG6aw&H1?c0_4 zwH_;A6$=(DsESojTxGfYa?&&P_1}LG*Tpw)4iB_sYnPXo(;eyNE?J4*PJZly^;cc_^ohiHXVNXstfKwo=JGQSCKbbQG}ij=sKF zJZ+KM^=0dJ?%3tp`G0oq;aeQ2zfCR9bEGdZmxrJK$l%~0+@x0dsA#x{2g7K0`9Z`V zK@p4eXw_JMJW4pWlJY|Gs#UA_l#A68bfSe@&K@i&DZyqW9sXe$K6Yt2>#y?q6aNSB zaj=TmO5eC~qanvN^Fe5+-}UQ%$Y8H-!g__=rp_*0xKMRs6@tS}gz3(no@gmH$3s58 zzP=~9^CcuCOzM*i{cUvMzUR)J>-g{?aj-cv7GAeV|HpjE|JsA9{NT2Dk+or~X%8~5*8=4k%)*I)iN>S-3uD)CxEco11Bul0&5D!ztSv|L=W5FV@UA6$$N z)J{D&^7*qrcB9;ymv7U5uwIB#K|z5c5^Ro5`HhWI9WcF{1?2rlZVO7lDoqyg{)leyDlS363Z*|}Wn>hyoklylx*`{|o!y7kP)x;7u6bRZEiEoSa(?lOnzm=> zIb}38H36p{oqjY?usPWH)iq`tJ3Cdx9t5hBw-?kPubr=4M~VNtul2GgPCPI)dlePM z_436FE?!w88*~C%;FQ@cA6SOKfE5M zDJCWsqnR9m{G*cV<|=f$PQi1Xus_`Uub%l+^~f_kb*k^p?d>A&Gg(`7o`h6YsbD8% zeU`I}@f|&Sv^ri}eHqJ+>zSFEcXpb`+z~Qk31m?%o*3?8{QdV(eD48#Zb9`Ej@*PygoBdE1s5?9)+)}48Jd~&T>3MIVzCJPuJc))r(Cu zCfIFKM$~EKdSqmzX>EeJEnkRqjdJjx8#j*Tv%6~)?#Dq?jPz8-PE|z~#sEN3P_+eG zm6L@5KsN|>A2-=d!tYh z^o_N;*Rs1$-ABIb?ypZSEGXcvwhjskst%L+J>_)0Qd*PERg3IVHK1L2*ojJ4Nsy!B z*9dBVX0%szpgvh@+qP}~wRv9acR#?}aP8TXc_`ns>B*ypRP$JE%WT!4Jq~ICTXd^J zrB(=;H#`ok2#t|GdbDE?#InfoIa;lW=<;#~nK}ss=YiH-{V!u5YXACi@z64MD|>sjyF1NK3f}JM>vmnXu6fy+%#O(CA;JcGs zN|LWG_-XNCIiCXu4ixhJ#;_}9>6$HE$X!%;5VApxB6IYaX>fP~Q#NhRNC6@U2j1#^ zf7ep2GU5n@yXr)JLKArINxP%cO3KOkY{?aS0ZjxPmq2iaPGW> zy$Krw#vZ{3sh8dp?ZoP^k@eGN3m6#p&j-D$qYqffg+q+h6LiXJ;jae;phggiNcXky?~svwZn7M~|wTn#L$8DG}Tc+I{BL zke2#^1Lxkgx7+pCZIe;ztBHpv3ycmnYoA}VOsUA9e_6)osBYvTdR|xvPFwTJKe^MN z?Ey%ZJe-fn3y$aszKeiBHi&t1!SjIhjcaV?IgW;~yKDe8R zO~*gThL0US=uJ=dCCbXm(xP@)we4HRE~bOMRL3L#nv)v!kNmy8CfxQf^YeLk?o?a6 ze0^DGQ2?h5g4{%*&Ze6(NRV_ItJkfI9Unhi)ZX&!{9?b`x4G5T)!|(wN-o8&{ij=V zL^%)nUfn3=r4bLO~jY+jbT*PLEU`o&4ZF8(Vx=m=|veufQIu1IgMpnx{nr zHV%FMTvIIEdOF~+`^-cnPKKO}oI7`BGS=*u2PAQ9%*)H<=(qj=l1Q}fDKdt!?py(#dB>Yj!blPoE)foba0P-zrvwI ze*-Gm4KxT5vH}^vBI@*5#9>h9eP7--_`CKdyH5FmhFtetM09+=ImMz`3(=%R_)#o} z#D%yxzUj}6mJ^%Ky?phmx9*Vvf&s-k1P%WD65UG&9G3IvE5|-nJ+U_M zT)XW685y3c=;UUvzyJOTF-ZpXvN|3I7AJXa?fqYV-(=kO^sm)yF(Du!v}AQ1Bkgsw z&MNv;#c3w@Ez#1`)ARQ^Zhg|o2nTbpmhrXQ?6d>YM=YT^JV?$0O>9MV#F2H#Xuh?o zQk*w&LU7_v-u6H-S1ovl0=R==KkKIEW>2rHvVS69|AI{z0~>0AF`)9IzyCCLEy}Vrr?)vX%?Xb6_MR;VCua}5y#_&IH5*&P zty^pH09=Syu+!RqR&L}eu9IbWcws&<`-x@JFR3R&zbS|6{wSX?q6c7Kn^xe)6e?b)exKT^sgVUT)kSPo;8W^ zz#)Sa_jq-Jjhs3vIUI;vdPll#kI&~1t-%6v$UWg!)OuSZ#EI5R8q{C`}DA6zd$t>b-S*A5{nihR| zYu5d*>#cwjb$M1nonci&#HVXoLqe zt&U;rJjBJ#Edwy;|DYIeKo*HirGnfEIERC(mt?jFnX;iM^*&xCD=mGU1AZtoGc)7g z7=d*COeT@A_m%6nZbiZA`+&A<0AQ*g9zVE@S@6*Fi_4UA-KKeTp2c#>$jG2R3SP~` z6oGB(e)sY!)pV|rM=>(IxKTSfk4@a3K_w-f{cAj=;}TpdBybh{f>PS0@)eJg{c8Sg+Y~LcK3x=>ojOC+ z$WhTz-%W>ag@D*-5G_Lb9&K^{K*-&+D(XhW(cpx9Hs`~L<7v)JO}D@U$VKX#0W*ohMfNv3MX~HLwA06P;_q!@~;z=95y4@k*zW z?)%7?%y;}??{(Mx{Ua=Mr_}(*RN?6?JB&jzKjdhSwKykEj`S#-eBM-ASg3^Ge1cH&|Saln<)NavUB(oY#g+R{?v4)01~=JlufV@6)GG{?Qugolyq)UNSx~k&OZZ z0@(JhyA7SMbHjptd`_h2I3|wuR7P@63k8)s^%cMu_B4eooU;4ULZpUyqY-x@Z90tq z26zON7W~RtvPs!o3M&x{i4L9ER7Ip9JWLtifd(+Xy};;$;1)!%*X;y07qh#B2;__( zAUuH>GxB<)w{dsbea3gkmGJt{ZaqVR=P7en<3U2zplY@uYe`tw^xe$?!at+m#5)2>3<9PZ7*&bw~E7z{6;ANCB zo;=w_DGCLYzm0){!u71ItisXRKd_e6nbP`~E2h=KEKd49S``!`S(m-L(mgqE?2RCQ|@zNhm>QNait z3>;@VGd01o_w2*+M?5J2T%C7M_ z#6Kd_%PDd=ywe;!^bpUvjy1C)-RkYRh{LxZB<9X&tq>azd0!fwh{s;b8Y``+sCWk~ zFY30q-Dlo+qe6`n+zFJq&_V#u^AD=&EOv@j=zD&%F^Wff9h&JaSx zG~oF@H`KXKeer2K0G^7Nj=9f%Y2`KNZbPkpN6a+?IWiO*+?zetqMT_zaLuc;42439 z`|OO%&FB*+PViM~-VwH>)Y-*rj|3l0%*$qn!^oTdGP~0C`+&d!mt}oyD~||we$jG( zk5Fny0raeZwGt;{H#FC#J@WkPVy_`9n-Uy23{ zH*DT4g|zm_*V|@R%&N^pP*4yg#{)zcJ>eTM2u^-(U2C0X4j<04V5vj31_G9cu%Bsl zZ-&V+Bmy|Le|b5pl7%%V505NrLf(f@-gR|J)i3Aruv4_b52(_CRdu$vD;r73AeY93 z5pNJ4pr?e=Y|%27umF8GO~80T5w#2W;GNl@Uagyadx?EDYR9w|r>lv~441yLtTUT| zWKq{vrJv~<>5WZPs~adNJctI*J-0~{RxuZi#H^t!dM=+NQki)UP$j>9w~r<7E7vcd zHB&dCvhX4}dNaZ%(xDmKCn=S%>(;VvX~q_WFTM*8nz)q_-DTzE zl251H(dH`TUxTC?gNgtjhv;Hsiz=&VjK^}NfT(Em(ArxLEVlvz0;t|Lyf?O59lT5` zkab&)Ef7scyVssVSF?;OB?Sf1bsx5MOmkkT$PrNV8STISpws%$1@j9Hs6#+6_@3oe zp}qAbBH`s4{VD*M$Q;)%y`I7?3MeQ&y*d@#W+qN$PYo5Jtx_AM7)ti(wsFFXbPjQJ z9c!}!oVD`c3ehk)wAo-&y3_mHr>=RaY$D?55}T7WC86BeY0D#lyUMZ4c>tcb6FGeM z?CymR`-A~qzvum>(}GpQztQTx%Sl7S9)!A5^`9D1s!**2OkDW23`NjJoeJo$`rxN~ zw{J(I*rvKoY42{wp)go-1cCrJ06G!cV`HZTkFljMOn8?S_NG+)n-(DdnC>;6BZ@H` zeb1}`a7^;Oh|LD@$v_OGJg%?b>M|yU()DgW_`ML>C)gMqez-%6qZG1XC5TT}i(k)3 zBqOP2f6QAd;xhj5p6h4L?8)BP7~Ra&@<$A9BJ+t=#SWxfHGqokVAF2b@wb=A=E`sU z8gTu3h;{obZdA5lof6nwM-)Rh))%9ISk2CE$?ec7e^KPj`)eFPU%H?k6p;$StyG1} ztwB8b)DV0=6VKH7g$;xcJi`RV7Yb<~4xsER!DW1DKfUklROQ^XMi=0M&@#vY;-1A^ zC)ct@9|mMEzP0V3WzIx|(VJWM(e+!$T3~^26=1pUY14wTmsi(tPTOUcYEKnRSBC8W z@%+uuIKz`CyAl2-Qai7CdZzduM-1I^^k}Jzg!s(@6_YE)0K^%n9u0Ti^+Rd)%5$A| z#4oVvC@F8Y(|>9H{f;TE&~%krOM9I`hMMN;YAb`Uq&Z`MI85Qp*Ze1bP|}(3{e+pNY>A|r}3bgnm-f2Rv7s-z(pDOyf{QQ7S^Q+B;o=l*R+?(NlNclo$Ke1c6@2`T}@rLVGHCZHmg z^! z;pXP%6NZN*dY&%4+r9E%*{|2F{z?Z5r9AEG3+l9z_ z&XfhIO^yu!LO9Uy#5xp|eszYO*@X)idO)Y`6j8bi}WaEW{L_)T( zve|W~@T_)YmgAff;fEg=b&JnVc%w|Wunk)x@S)~P>Jr8DA*SS^q*2GdQpV5LgBht_ znoa#R0o?KyW;L~~B6saJY3K9yoBegp^>h8HJ9{0Is6$X3v}Y`%lH28nDBsV6&D3b; z!DEBHtH5TN*@p4Fr3%)UTe)L!FoBU*EeZsYq|^e2`KmM~5a0HIN~=XB`1oYODym#1 zrD8r33j*_&2Jb^Vj82cI*GXmUMCY<@7*3OL$T}fYUrQ}@kRyhIw^hH#NS!uyhTF462u`grDE{^k{C7TZrBU;fF1HSy9N4yHA!UKc?8Q&ES=B!()>> z+fRXoJx#gqux{ZV#~$?K{Y-mTtv@OgQP3I0gR0En{LNWTaFz&%kwC3rJPLUpnOmA@ zt_ck5E7DjPl=e_Y^QGtq&%@(9gVwS(T7#nkQCrnoYNL5b;=<-WWj)uaE-&p?&Yu#bnt-!k5<`B4O!KnadZ+7v7dAgH(()tkM1z3;COCx@@uHv#6>(B;A|m!yQ96;Xw%)c-zfohfN+SsH`+Co;zMW2FAsgL&&6}1E7p(6zDCQlLx`Mkn_*Fc!!OWQS4S z)lNOF2n;lk@fq)CJJ#%=EoP4%8Cv|qjK}f$*qZz=d##L#9tofFORGDJ_*>*i{0h=p zqfjmQBO%08bj4f&t`9FrQ3}jcKOUZNE_D~5vDu3UHC#s&3v2AJau(>aT}V7Se+^_bdL+4M`Xg1=m)4R)?uk001-txn) zEbIqbfAaV5--pbK_hwSS&6~>i-Pi9|+&y3|N^B2=fKch7gJlgz*fJ(G-ye*5P^;&B zq}65E6WS!_=Z1;v9Gkg581m-zDTgCJm?L-UQEvbE_PL+GzfoEW5Jv(^^XYc>*)r_* zC`zL~^a1U)XC>>MScN{cN@SO4H4U%!d#1QcsV2z^NkUU zpn#6u2OQsTZ9tJ613dcy>#0HTS;p-wqXdMudgaRdkQkUg_4vVmVDqP38J+aF;7SeN zV%Lz6$}4B?t<#K*8rF1A2pfxS`cr){c-?L_)nO=8dV*)CBE|5mC;YNG$j1KK9PFZm zd{zaNl896GE!Z|Z^IPE;$Sr1`E8fr>Su1$*pPbnlXX4e4icN$y*UYOKqj(Tn!T{*Z zkQDtdbBEi7Ca&w8E}k9IiOhm6^&mD>0_%*Tf6-`Xj#f$b#QVDq509V6-*M>c>!UGL zFLcmEBlp>=;_CU>*FB$*;Vn_Bc+JXklWH@xppL zb3#Q79)1w(KU*##^rBo0RqY0CRfQP^W$(Zmb_N5QqXWgiMLTove9w-!OM8ch{4MRY6B(ddSuChBhY{adkhvlQ2M#_%lm zVBX30S*$%8n7OwzK)(j0Qi@6Cre>&aCG#O291a3v;6hK+b#kN}{H3Rt%5jY~<>o;~ zx=~3pF8kTnq)I9Va9a%K6^<^{4L)a6KWX54Cw|DiCGS?~GL1)zlk4Mv$#npB|H_%{ zJNxbz>}>I1UmAG2w{PE)s$rCvPvl`ni>p!*J3{^- zLKN7AeoT~=3eptN$8l+YfMQ*0R&Mm(d*byZV>7BbQXHTRE4e;;{@l6M_y)8P0WZ|R z1h+P5dL*Sno{8P$0*6o97o^M1ew|0AEa|_Gp@mA#YVfob-O~HQ1Ar0$p?e@Wt#qFm zW`{N}^+mpwVC&Q5kKd#)CM$km2={@*z$d`vA3=8GPTMTG&@k7 zLAfC}?m051TpYbs{O(#OAD5XXiCI3hWP?b1fYP_o^`x*z3^xRZpk%Ygf5pZDOihoq zqFUJFI`t{vX{21LsQ<}@>;#p%K6OU{vuR810D+P|W#LH{9nD>?laDE7Ut)LDKueE% zxP476O1IIngDcSSv8Vu6*m$$xq=tW%Z1PJ5#V&#Vy%M@PI~;B5Gd%q|cAo0XQLdUU zn4D3n>r1ccw`1q>1Sv|rCUC5^poF5){aWYWiDMv@P0rMiT#@tL&Sy1dSzAe4YzXHHG1-M+QTCJI$wRJtjtWC6dJq9)w9^vGA1wjB&Q1MQ@NeKv)X_;m zZswIZGPQkDOrdU?d6s}3^rL-H&XiLHlsT9YtCAnBQLV_p6>%!qRSkGWE9s<6dRp7k z27|hqv&C8N+TQVxQ%aNK75!6d9*VhH<6qeiH#11EM#k;hv&XE!hw};w#j0rKBEw~K z_UsXJ0@MicD(Q#gxV!Db^Yn6gdWG8LX>T1Zb5eSbazy}xQ1DV0@K0p1b zTlz|dC*#=8fH6z$NJiV42V2a{iq8$Htgg}C#iIGyCye-iG{33+hQmKkQ#sk?rho@M@}~U&oh|ePZT)Q;y!+K8;d}r$x7{ z9^Iv^aq*o_?Ys5QMdb82C+^f~6|s%o@cGBnla!9oR;-2`mPEyQ0ofeUV3e->^N#`^ zw>s0o62SXKxAa4wF|p%)-sLFu3qg8;73$VWEm1HHGte?9PHrY8Cl}fA&u?cTkC2cm zw7X<3g@#w0Wc1XN?3m4J5`!33E^>9R5h!{m^km&9G!J^9VK(I&l(qDgbmjFH+OBtV2-JmT{2n|qNPR8iZPKT1&c$v^*&%RBhgLO=C0v*xjf zRDH%$;t~z4ExH!!MsSF?UmecM`xy;K3X>MO)AmBfW&4os!W$xrr3n~=2(CuCMRH3t z@V1JqQZPYnVLZ}Zu9fSSU6ZJv2*}n{_6hLbY8S#FLF#)hLo%6(x*9#PA(e%h&jP<3 zO5@Y}^`Uy>B!XZSjGU2;O)sHuKEkS~iO-COg1ff+kUhr28vbVW=Sko4#Al>b0{Q`n zS504^%K_>aWWFV-_#vhzng>FoQ?`7UjAB(Z0)384aINhy5^~Bog1!!|qiA3#KCOi( zK+sf%1jgXF&}ZEtawY7FUE`zoz*}H7%%Itll)Ay8ny9CX|AklFUCqqQ4e<*&dluF{ z5yJ^l{@CDC!b49Kn3!dUg|-cya?zBLm8}3EB(<$Ex{R;-8EI*cny zw|fXucal1{Ka*Aiw-n? z0r(qKt~kFx>nlKJcMJ@~gZ*P>eYxeD%d#!%;C6Ub>f1{8e5h*4b|%fx!L+k{B_#`9 z9=AOn{p8x&BRee}pQ~}_b@Lb7q*)PoMQza^(tI8j7_)R%$Rk^0~F^@iJ`#EiR=p!@%G3dG?yins6 zkUV9HqEq%tsFsLwCrRY=fTepSIwHiu78(eL`2^ek zbX3YvVMjfE`c!Z?bxxL_LYuL-J~{GuUzh8udtBNO72B5Jcmx7wR(I8lHZ;@N;^(Nk-ERnu-C*qe}x)y_D-Z3-3TK4P`WM71I^K zin!mj_cD#Rau1sMFdDwQVdwS0roPYfb=JZq+Lf=aoiJOP4?38|Ki?mni)hGaN%>Z; zIK*9Ipl>avU(=9gnTTFE^lWGBH4~ozN2Q>q%KkE#d1sG90?s)ef5+?}x#L55$GylW zl`*oJl8Rlt-Ccd2>$@aN40xri2N!d?>M81>PqM?jVF%@T5KJ{VOHy0b{@O{ON=AdW zUsa;M_&`&7Ww*3&SX9?z#}C1siW&j~EaAGPdWC(v1Iu&!71g%r=fok=@q%F>)dwVV zMg4W4Ds}~;Ek_~JUNbi2)1!q!dNq-n;-3Ue6Gz`ADEjQ}Bto8=2I-0Oa{vm=#Mc59 z@dOwIjM#B%C+au9?v!;3%uDj8uDG-hS{?cpX1*6knY_XKAt*d_Ufx$Al-lyN^vlJp z_+QqfmfTdgzIraa`BmIQ@A%qBGcS*6n`yh3)Yv84)t~cHEmQf;`S8*tf5?fUA6k-j zAvERc8UgB@*=r|;B~EJxs|Du281nscrW4dWc9;W0A0sb*KWdC5odMMeiTS}`t@U|c zW1y|*y||_;Ek|ID&~$9r*r#(|HywiV+Q{Wn|dZ&m*acWEV z#4XWXPCX>EgVv}5N`VN}wtcCM7QB`1kgK*?q45}g?b@%Q25pN#RYxJ=NaoKwv6XZ} zLIR_aTx<-ff_%^$J7Kk|aWHFGp5)`e1*Aw>R{w6B<&DG;^TkUimCGELh)62-1?+S` z&fcgM`tZ%m-Ij{_i~CIea1_^Ps!iWPBsKViShwlP1|-u94SD5S61Um9xOgVp135r3 zz-FjPP81~(1euIgvS-*!RjXXVs#6?akD=V;u2a+2GBdvKGwOzOX6jD` zN278F6ONKNlUn(8=H?sGbe9A9O`6CZXFnb@uTKI4y6=L+%#Bdt`7}W zVMf~Q1)Ff8DRoQYm86#&3nh;$oA(zerdmC&!PpDR49_q7w!uKz1C}9hU%o^fDUv9M4H)) ze^!!u5|tH?#F4NfXSP0fxrxo6>v@ha?zmCubxvu?FTa$d#H0zK(9n5r*cEpC z`9<#CyKnQ`^>YB7fn|s*)2`JlYJT?!QDA6vv>LrZ;N!&r0fOLTDK;>=EtN7$Yqq}& zvLh0CV=e2;4X2x)C^|G*Un<`w8-_SWsb}QXI?HZ9b-i-10k%UOGNA_dR~3L;BwY#m zm@%mR5Wa&kn_+3o_x#C|C&p+@5G_W0o*8yWQYwkJ&*XUO64`}EVv>x^dT)u=^SJui zYTb%YeCg?*x;}k`wA)cfgT<&V3H>aoQfzd+AxOGZ2}`F544`3Bte>=9?^}k&k2IYr zMMLm9KkIzLk|ot8v>ilel`F>ljhFBstNqZm*`h3rI zk=)7=^qaY@z^7JHdlg(gZ0IcMXzly!?t@ra#~S`3FenIpxE(aC1eGwfE#>&EYhD** z+W^q19Zc*7v1nS^PAOE&V>8f5=|&A-{r4}w?*Na00nz?19{_?En7&-cQDN*mIakKKp)M1 zXru#NTiOJZHg6J%#o;`F~!}4wSYwds| zK_aT8_Rg^Dg9F^BnL1x|+7BMFO0Gc!B>%vuU>P=rdTz1_Tq)4)#p1v-(2O7+A2K)* zTjuaM^nrSwuMn>y5fTkWpoJ9J9w5}TEVV{MOLE) z3Dsm2wBPoc0d&;Fj9kC|8zP-N0u5KVz~W<=OQl{A0uhW}5pdGe>!&%3Z!4SpJP=C? z)V#lcp-yeNHBUG=%Vzi4X(&-HkklZwz3I0;ezt?;HGePR;ox|2Jk9EHI3gv>Zkw=s zPQBcP;tT6i&F{jmi2Q+q?oq2)0;)@~Fa6tbSO)+}0#F~JQ~@sDbsg}`1bpX`<;!cR zElzzpNY=YG7-^ob#j%T(xDFzXMuE!Fl6@howIyi_N9RmtNc-xsag-uaLWQP54@yo= zr~9}K3^6sGHs9P61w~;94RwNit40Tp1H$mk_<=g{M?a{TP&~vK?+ExDQ&b3O^a+Wq zT5=upC@{-D^Z}~y+p086{m_l`j-avx@+1=XLh>#?4MC)2ezXb-ETQ9hKhf9&wb%gr zJ-uw7+oYWh++pIwhTbKp?;8t#<)a1wRXa4m8zysez0K16b6GHH8W%y_H?{R$vKcKf zi~jlNpH*bw&6%|*ZIhr{xBJkdyK?19`XyFkXv;BYW*)MkXp*4Hq!~Jz_(92o zgH@82lOvrXiPk9lp{=o9MCmrhtnM)JX@sEPZ;H;)=}$k)%r@o$l~)S5}H3Lj>AUe^QgFmM3mB>Kv-S(ZlzB`Yu+bFtOfC-wL4GW z5}W#X5KTcj(h-$g|LXARoy4;ByA%*iYG7sk84LYH5p9j32_otOb7a8zBM3=rS(h@t zhD}#NjZcG~L~W1a=TX=m$$T4Ww8(2w#D#(n?Smp`tBAbV!Xpz0UaBcZI+Fr_dU8}5 z*y6FE!L3R+!v_&WC@#7t#p{l#laL|IO(=-tMb}17d z1pJ4>nWyLJB88RE*6>0rMY?U8mqXKz5%;w%& zZ+$?eYW+Uxm)lkbT0On-(+}KlK9;;$bT@1->m?k+m7%cPtb3eldv-)eZ~LWXm!Qan z;e9+yMa#MUVs=eRE4!SW9BFjW+*U?= z8F7k7N=gcag!jtq&Nd8p(x$FwWu+9haPeYZ5Q^vw#qjY@*nKU~YDm&g+6f?mN>l(4 zI6i=R+%~`eR_~C61W6yAFc(8_08n-WlMvfP)Y8WdFXy8P7O$BsiLMCWC*wsBwULR_ zPr#_CTKtkPE=XZlO3Dmo)Z35}3jvv_ZJ3R+ib@zdqOTzXLeN*m6qSf=_c7Zz8)YcH zDe=rsb&03g_9!8AT&>-+-EMl)E_A~1|OrgBD`G%gK&@N#i+~pb)G1E{`^@|YCb7% z-Gdf4X;B`VRPJz}aoH^*(hH(Z)xsj7yqw23FYiFSUbdF^-l2bJ1UUW7Db`(9`$!*N zzgpjoABs+tNrsoDwtp;IcJJD?mbK_N(nF*2H#9fr#|vC%Cb}f04(z58nGA;y2?$fDD^({UB~nF865F^N zgB7(TtHGgkSF7vCU+-jX(|hsiRbg$dIw2tH*x_%OSuf|U@ra?=M@=L2S|8((3=Itn z@H*N!06o%VH|MxEcHicqj-xAe|t^)lDwY$)dq9|FuZ9Z|o(L#6=GI;eX zGz$lSTg#wjrP(v`L#V(6`>tA$be&=q5V9G-07z#~YT+Yy6hU{;efHvs%lR?I>jSK& zHp2XAfDu<#P`kLOpg@LNOwdSpda1<#t_b0x2WZX;aQ+xlD+g{oX>M+AyW`+)u-pWd zcUeE6E<4g^;0aqsOnp<7iH7bgDJ^YoC=sj*G}`>Tc4<&cb9Uy#tSO)v2J8hzR$1v| zu#e^d(Q%=PGRF4~Q4*hi%!*xyJ`cwy?iCDvuMm?Tn^yCXv)~DC#K*^z;uLMs*Ff^9 z?Ioq+u7ks*;YT#0O~ED>78Ow_9zp-n40+sWdkfpXPPz-ilX?5AH~}L{Hv9DS?h(I> z0_rfVNfk>O1`jIsId)n5c^;In1k9JP-k(L#7D(uSV~Ru2I2wR2h0= z58%KotSLH3)e_j3YRCdp4Dy$gYJukDf%IX;;b>&h{Ir*sm!#A}k5%)cI|c`GoSZL% zd&ql9#Dljd`yq~vX2j-T`S??$kO&yO8NMa9m2QmC*4C!+Kj1~`SQXpUzjCIo4XT-z z?zLQ;OiWCKBS}>PWQn8F)_Qc}!dxMZexi-7ElxRmC z;!NlG-FR(bf^^X6O0q9vnEE=}WaU8R8QP~Q*6osX0R`X_1R+Xbji_2e5g(1BBq=3D zNTgSnk%@`M>cCy4xnZ7(*eY@XH@6%%xAEf`H&DU5W7IHaq-%u1Hy8?}UNA@7{0vyv zuO|+Q&J#ga$VKEB{)Qq8WEJKh1Tc+-NA*Xm9wT{N$e~5J>Y(geR2?55-`o@^Hk;g1RcnTBXUqM^E_pX$!tRYdAUYM%mm#aS5&AdE6JRbxsx1<)HtbCi~eu>%^* zMVipm(uzU2p#X=(4eCOUW*V0-UvAoxm5#9r)A4oDO-(w`Rmzio$qy}8T<+0}_HE(o z*JX$-G>*Z@$Ow0mg)!4yDEN~H1afXju_?mR+#Pc1BT(5A@O|iaX+Y7b`~IcEz3V(;EKwa(myvXX@X_Wh zM`hGj#BdRL7zO&7L~76?sURUJ<<5eO>H!BqLozg+mSJx_{QiiLMUw`m05GuX51r)t z_3LG)XB34L$Iq=q^oQg>6fCC+$=8M)III$>;H8O)x#)UG0C7`5*$5(GB6s-V|1X8_n*0IwUM zC&0v1r$oxFg~)~Q9y*TEOrJivw3A<+YGME>4S(g;+Idk zfon3sq?z2s=ElGvP3s=s$L5^Gql2@5T~Z=XpNXeE2_P@B;2P9Bgr1eK~xGPnzFc+3rz*P zj@K&zuB3hX2L@pLMKVE9m+vC13Q+F-JrnKzAUZql<9ki>0EUaHmj{b_3L!ih@E2 zc0+dZ=PER|3))sP$$47&ZQNPNxU)UdZ+5A$TW=_h~v}8er|)r4=LzMgm5i)WF*H z%xxfG#r}r6y4N)|Y8Z19@_R``i}?NB5^EaxBH|n=$q?uHRPo2BABsv#)iF**5gE54 z5$8-hSyHkydkZ>5stB+StBp7dUcHjUmaF01=s2i{3!qC~D>kR@4dmyDD>TpqT(V5$ zfQrQGoMT}m>%o*Bygd{X+q@$~Z@02j7nt?|Q9=QcV5dk)a1vc)r^1Q%1C~<9xfM<4 z3=a=i0}#^$Iyzn!>CK54n5Fr06mV4bQW}S{iY7zsKoB(9%vaVSQ+4(A1+ZE$+Sy(1 zMGK7>R6X&9S(#YuJPYeW=xyMSCh#H_sLNmm=td4_Rv!CnXb8PdW0Vqe5?3TqP&q%d z|Mi0hPaf7zDrY=$2pi(VU;~-*>>Lh_rAS-FKGod*pG(H z!Hd6^L!k+}ZaX!ZX+UKX`IzTOy&Q=rRSPj2Ko_on@1rWi=NX1S;U9FR8^R5}k?3fZ zGD^Db9AB^a;_=5C3ozO@cPZdj4QNCe+1V3etdzHaejYfb(oIl6iub)3%`uEyI7&Tgg zW$GX5aE+GKr`8z?6c$zqpOb)g zfSkSHaY?rZzKBN2NHGN;7Z&--($J^n!MhUBRezeEX$Ju)?E`?AskHPb1};{8*HJ&x;!(`QnF)!Muv)a{#3OF> z;z4T>>_>=G80sj1{R@k*c<>m55h4i~TU)6fJqCR#EZ>6bWl#^$L?8`l!h}7&{^t2p zTwI?>AfUxaz=!>zM+AIb=f|~fA1jkDC`8OL${ulZ{xW@%OVyONeL3T zw~*;c66nt7Vx;rC;*5%w3P%bDNGty3)-!ZX1`U2u$qnpK3Gg|JVK?>hCI+6J|E?h< z1~pC@F*?BVp`jt`HCb4(m#GxzVXxSPs%|cKU{$9(qRy!mm6fCLN>h+Wgtag^^E-8^;0y_`O%9lw7bp^3eAA8oZ4y5XCn>ZobRxA$t{Ob?Y*wLWu}~D#_1YL=8eSx@e#em6#9O zsnkb6NR|NOgYxTttDW0GLofRK8(fFS|C5OTBlL2eKi7Y7iK zqag{Ax%+75-^@21NW7r3vJxfNDVW#OH;048bdka;kY8barU0sOpzx?(KqxJvJ1x*V zfX0WJb)K}Gdmj%a352pY*Ra_wu49;xl?Te;cwTz6>%fuh3OH2QQ%P>5>lzWM($GaILlV-S016}oolg0-iSW;^Kl<^*0 zb*!x)fiI5M*D&)91d7 zC^rFL{^xw7VV7pmn9|%2N=ys96Lp>DS_hEgR8&;ZgdRu+N#yG7U$@qy9*RCs&>UYc zf%T(K?N$RCsYjrLoDR(r!BfYN)2R^e%BvPv2JH^%co2}}p@02m!*dT7atPSRgZYe= zRT-!NBF~b!MNtM}Y(SCPTSNo!;A#uR)JpUYq97z%%Q~MKLkjPT*u_B2HGc`O$}d1> zHFNUbzicS`ywSm4Q&Stg&b6%JI(XM!8VbX;X(MB~vvlbNfK0hrVs-?Q={HwU(F8w5 zl;xafdGH*^gJ9Hu=QndavvcQ8n){)tX~;tX9`@ky$*-u;p?FBl4iI}e2Bd&0&29J2 zAHm$e2PrUykY6G1!>@R_xVDOTZ9uGxP}g&mz+F_eH19&*j<|Sd_nC;f-tYHs!9jNv zPKgtHsik$tpHK6I?dpT536#!d9_QVz$nLqzt1B4)QpM<9!fyr_qR;b>Ggb0cKH?VeuW-5|YnJB*rPQ)+6e6WZp~ zrANXqMQi8^?inKqJ8BrSH@CJC(@Ffa`&2u7hU=Hq@=xDws}Wsy+_s#i!_jd;TT?|x z=d^9$l1R)q(S^mfDB~c&?@p=JQ^o-JD7uO%)EQiLhsBs8T$bF)-!69tF*oB5lG=Ame3sq93Q^-xLzH-^D$ z7SjdY>ZqmZ3c_+lo`o2LcO9)(2c>=;wivbf-q{0)2$e`5-y*ESeY%+hWcBxPpv?hg zm@&~xa>2I z60ZRR!{F}-2v2o!sdW?(97zxGY(coYgzkJ2hd>jxAIj#fr1pW>?z>or;@|`sgM*=g zK`8ZhPyirSBGiUc(-PMLl4ODSCL)mlCFn}j|Ni{}`g?aOMj%vBg#RPU(0YjIKz>jn zNoPw|G&u4iBsSaF=^df}o)L~woo(Fz4| zAPFOn27e0_PlGAA5a>Epvc9vUV=Zf>EcNq9J%FSGt0p}GN&W3GDjFI(pNMH|qc~7i z5(O1%5E4kv?)w@9k7}~f5nNVM+0CVT5fFmzp@PoO6m4zH)_Tx+6GIA3_BTG9sz}-nr;7z- z4?nrXs&$z9hE$Pm?tuI(v|VL4$id0r*$H-BiP%e%0$>?Bpo~S8gNnN3o1cZBfHn<8 zl8^}Uqfs%CJQzq}eA6a2x6WHw7?Xfr9MBN;kakUf;_Z^oVdK?o3S;mS+{N-jSZ1V z5AK48R07#OGMM>+2LdaE*lOIi!wH;ABg6l%NNngqktydZ=}O|2{rk~Mc;la)olTdp z&`pwb6*e4W1WndHg==1|d! ziGNA(jo&SY@zDQ4OAISs;C{uMn~qcj?mh!L$G~>IG|6O0@`&p*q8vW7khX~22Yg-Z zlP7gwZT0CJ>>aOwKMZ-6-k={+Zl-$C}va7>cg%NVfxf5B0E0R5b5+Sg zW-ww!eQRiw%~F#YpZH&$qIxK#{@$pg+6`J@4017i`0xQPuf{XCP5HN^mY?Sp29%1I z+Hc!qtLV;lE$#gGA^hKrx^AT=Rf2RH*bf1??i4I(#HTCG1ibz?rOJu~>0;^oDQWX{ z#Ri?ue)%e_#|!|LwsD6>M;ITFGiPA?KZ{$X@0b6ivxhRUh0htuJr!>b>Op(gKd(?e zZ_0a8*RMIL7JsgZih<8(sg#Y2Kn~7w!K8Er+ZdaE*%N)seW>}-5P#l@+@Haj0RPnn zA$@{quhgAdGpDWCuJiDACy|HgOy*)u;Y+XgFo|^|AYePgMdIS+P6Q+$3(6^ zTZAw&rx7YcHPN-BeA4QF>~_=naKO|jFe;P@3o-`>=UzKo$r08*11ca9fm(O$xXX$% zP3(Vf_z|x4I}Br{V66mT{#8hva3TH;61%SduTpQVetRV3N=0G4e>} zFlP|FM8Y{Ya%}qOp3t!O%4`_Mi_i`zq6Iv7w(8470Q`SbhiOfM)t@9QVa?Q$xrj0K zWY-8#6s8h`hBUb;71F3Z)nL_wnU$hdt!uq^!|P0*RNmy zTcnzf!oOl>x%_13Kp1mKYNAEVEFlY9+cMzN>zSD*GIJs92!)zSm=j=Z_1WDv#kUVd z+NO`+RezuU^;W73$2EM$$s92zzPe^8;&IUVu!Db4DLeD2N zrNR+nrljZjRn94OWjx6%DO2$N_SaK*R2bsvaIo2td3Q51rf?^E`i)UAc*zTv3JvHT zM9~#1Mw%RfDaGbcYDFP*0TzRCmy-hp!^C4%X22xb9l$!m;Vs9cdSH2sv4LE#n^yrw z#gbSg$&6Jz3bqUu(%Xbgs;m>VYFG1p)F)E@O3f^KSTWjNeDUk<1Kz(@R1W~>Y3fVq z#hn`>|3B=&s*!oooB^ZybrcS5HbQeRo@rdXl0<->OI??AY@vA{Y)L*Hwxfb4qX?t0 zl4g`4PY?0q!?y`c+B@;o+O;(i(aR)(8d{(Lp)d;ge{+Un?FL&TBO~Wq*6CG!QC#}N z+2GY3|@X~Qh0T?dspf0rb* zek+9?On}N`xm*aTdR}j>tDx}Z3?o|deHmFMHZ}ve^z4Gir(Fz`^7;G1{cT|Mi;)%o zfR)VYHCyU_io2Eh6?~Zcgz|~sgP4oZZ7}p6D_$NE3J=jsD%ZeGdhchx>fy> z&+664Z-s@tAY$TqVQJ}}zL4SM1LjI92EL!2@i>(sm{4$O&_ij^=F>MqJSorn@cY}j z-{}a!FTAEDL}VHHQ4T+w zqEL)Ti`aK-c%zaI>rYh>6%OI$ia^YfDv(xru#U-kxt^dv;>`_4HhXV)v8j=gTRiPJyMXF*G~!TiUOUZhAOXa6qwAY)i_^Ojc|9%|0u=v%>Bqf}=K3!!?2 zf=oEV4}*JWg8YDoD9)YS(HneuNGnV-MpE7}I+R!r;^g|H)SjP)fyp?a%C>_RSgv=! zT+{fQfb3w*LGyBjpGjFUdw<;)R|WB;^^yxLr-b?sVopD>ap{qT_rhls+)h$8eWXmG zHwSDn*htdipVm%7aiqO$ahAesM14l;$urx>{TWjXrlzuWF6Eof;U23Z9qkKGo zFG{ES^*22q5z(V+?tBL8cF_9WYne-yU-{CKxII=QXqrPVqHCv}k9z)e4)hZwQ}1wO(o|y)&KqDbOKQ^xz(?NSzhN#8 zrTF6hsWo=x!gH9oUV@oun27k|U)$m^K&M$x<>}txJQLc_0WF?v-@aYuuf&JFyH~#_ zX7k_1);PJ}_(yp^eg`w?omjVU-ZcbcVst7liK1r%e?QX2+>sl~z5zKUq9Uatl-&UM zr3FzkP;AX|9iuQiUzl2DFt2+uN8$M)Y|mg$hBe1hdFcS)Q>Hfl9q(!LlQbO zK(nOY-*YgX7XkCA#C`D`5E>psA?@=(O*sSw%r%qSq}cQSizN@F5-s%>#?{;j5>&WJ z7FCYem_p6UGA%`t*(0QB)iDJYOn9Vk-z_GlbUE}K!roVDttsBMWupxIty*4!xFe?M zfA>NR9&7|W($HfD=tt>@R@6qE}`%H_55DB+(NRpD049Z@b zLt@}uW@QGlfQOL30|}=%QhfN(ciOaEm+=h`^}&-*8V2%1>0;eGR(w(_B(0ZOn}y6w z|7c=w|H4+q(-(MPze;QtOutjl=6r=kU^$n3AABs=Kdnci;KWqxr9=j1X7{ zHg9ju-FP+<*dj;>Qn_&4pr=g=jrKX=`a)~~IjB=jOvDe0d99JGAEVzOlp3BrNKHQV zC->Qk5-?FEbg)C;VLHbvH^?tm`w^1ax^Xc zzK*{cIqm+mO+kGj=~B#h0a_N9AD}l9v+AsmErWyZ=~fsK>0SKKo%_>Cf%<&i7vanw zkcxQXjwIoQaKvtKBmzf#3+9;J^M5r1e~t`}g0uvD0d+zr#jreNacZdsqdu*Xo}5~0 zqrGq~2F%-f^miZCugKJ-F{^!yBc8M$cUZ<5j0txW%>>K9S?2LO%TWnGzFvut{4jgA z){>i}j7(Q*nw=;WNP)s=>J8bGB5(xHhU*GdFTZKuewIMZTxLFbPuQZ89)PE0e_Ph) zwPq_GAE~xV%F^CTvdV&qA=|#PmKKzhXpj;|=G~)26myuYrAtwqk~sFM4ms5H zCtMrhLY^R@nVXwSGbZLqM;tCIK+zCrl;Y(mcX6+7p%cXqBrgch6@zDYfQc_-G9duK zzdE#A0w(fu&WC(tn?3 zDA^I>pDZ-#Hh~(tDEHi{%Mm2wkwS@qu&z!i1LS7_RwrHxMKoc%_U?7;)vR0h?nSu3 zV0d`9gHk^#wCXy(Rrx&w=VXo5LSK`Xlso)UeKm8Vtary-=!NxLMZ6Pl0|^pRjk&l0 zu{rMT%)+`UhwCRn!V~aZ*u#`5L`$*O4%ah5=Kpi@bOT^^m3Ex-^ zTh*om2YBzv|9q<~jyNTob%=Zt5r`hMot&mM99JuU^nzzeR;VZ-I`5!!!J2u2YuDB% zc>>}-`IodL$RXA%LbIo?aHAR?7QYw|CXtQ8iF7M@YDMdB3Pppt?t=SGOjY>InVeBE z(-j7X?x*`BUMrZqm>KzM$wuoFkfcpbUM{`JUp_o z=`{>sf5bxabscxPm}Ls)yaUmpNz$U2-LY?9ySzXHahfA^@J=L(3mcNyEh7|q0uspW zcm?yG^=F7vjNC3#7X_5uE+G9uyOMw&49*_pOUWiA4mo`lq_4fwKkaQPW7ei0-Uekp zmKZ>lT4(54gO9W);63k0?22NM!s5L*Nawj_qsEzzCYP6G-HbMK><*>u5CJ`HHIuEl1s)HEAEADq+6TEx7~j9 z(4j-8H&~ny(hXw-D?BU4j?)?@tK87%2^(C5Bd{UNDY2nu4gr5Ufh3^YlY6vn5>^joj2O|o%xB`CuwI%!>7Z^D z9dj|Kz0ui&;P>D$6NM@Z@K80XLJ%S0-xASv?|X4|df*u*Dpe6liYtXskYJ2Cx%SCF z04i9>Oh;A=03-aZNGVmNcOegu&Li*VXd1f+51dyTp|BgWGhh1#q(eGxV=e;sxZj_8 z|MlU_=9k1_oJkM;ohWk2GL)-nXz6-j$lKKR&L^>wZ9DPZZ2$uVPI)C$d z?+{7~a}JsN*0hsl@{@34d$#;>5!3}zrz|uejSD%G0JOJz6oHHcOd6J7q)L-In1m`q z8~Lfz0 z$D*B-hGNO9gS`?5Lik$%Ko(EJN_wpmA}E z)~S{L%`#BOpJF%%}lLM*5u)13k#~+}vrhaTCsf z>O5~Qy&3g~JTU?u3Z-5|RKambEy8w&af|uIU&^p#`LW|_dr=?#Y2@-@^hBcExXy>B z50mWA9W}Uo%ZN_%+JKC{Kr{dC1cg{45rX?2eY$s=*(1yv?L#?bMq#o{@;ESZ_{)2& z)HE2dJBsuJBBwpkOYA+#sA`KBFBbbaK0Q&Z@09S&ULj^~VP^57M#ki~1^Rz<5VC@X zV5B|KrI`7q|D--hcJ-mA4{A|`(Z(sd$l#mv02QJ%`~9%l8vXS4>z@}GJ4?C72@s_< zNlz5>pr;XV(k;#(9%uC!QoV?2#QPtJz1j)@?3UT`;VWTnp5{r5mvvNR0^9`|&hYlO z9y~b1e^T96v@0wV;%vyvhd(JJC~3eDJOLsMD4yK~kS(0AB$HvBf`nkqP=U91oOeux zxr{Kue>3_gQ5t*dP+8l@S_xsPm~R+)_|EIE)r(jSrZQwA(ua%3CB2;hSluV>w|t?Y zfZ1s^IZaB}xd&E^r7?+U9ytPP*lrmFgWt zT%RJS(XeGkf*P^Kv_*=rfapF)-%X=#SX+nnUuteWI}-GVTOGXHYdCN{<+m6Jsq^SL ztlfI;0Y#Y4wS-^zfDA<8Z~}}Iil#1 z!8NPYjAwiGd=|*)ilRfdG0Pqx5e?B?sH2cV%d>OM$I)!}BF@MsmiGv~TU-RFujM_S zpc3^?3?x{I(}gIGSx7Ha0H%H&*zA`E6Y$)5QW4yNP@KqkQ8{D~qh!C{tGfW884kpJ3N23_&=Ec-$o zb%;XdI`|IKo$#8$$BxbQ_Zwq2z_-;Uuf_APa4h$Pk4E#mbKXeu83m-)#9e#=*@$S^aVw8gvTJQg@E{NO&W8#M8U0~X%l4KG{9y_yVnXue}EhxX&jo;Nd7l?rc0 zofzRw=mSX4q)Vmq>NRy+p?D24y@2*P%k_%#+nlTCIhs_x(@@cbw_e^V+2}>(?D;7i zO<}u}Xk^K5b=Mv7f+9gS))4??p1J7h`A$sovX1teJNGTt)hCW1Gorr;e<`FbQ3GV1 z4y3#2*2@Xvac>-%d08?X;!FrCkY%zT?XdCC_IJEZ;KZ2n#<_Djsl?~A7P{3tn`J1$P4h_ZR~F=IyF67y>cTdDJYS0w)?mmUB)HEMR{ zX8Gc%6Q9e)1X5x4YbNZ{*^0HdFp+Uj5L+)Uu54Qo^JkfkQ!g3Ag`%_A5}>4zqF6E8 z{f7K(?kx;IvF!|Bn?uoi>!=S)dropI2#-(6a3W!0yaGT(^`P;!;-732zTviu_SP#V9hnfCc_5KTXPCvlMU{pyYJ94?DF~Nstsd0yRTRgYuz?BF0KV6hOM_= z8~56E-u+YO+qZA$7Z=x$wQSHaFg-EbdeWqZ&6SmQ8obsIJrmz>%7cVC&Ut`{p$!)< zwC^2iTzA{}D>@6zrcPbQeY^hJguCr&FV^8X57EOnhCeoEhS2p)QpTKGhi62E7iOaMWpw9lqdISkInd~0=)Jdd_3C!=X{=Yb&G_u>>_>4< zt?04>>6z?-y0?z+Y7>;b82oHcans=)8`0^kJ94B;&g>@qp^J3Qw`)Z)!^wF1v;oAB z?(?oL3yb_ENG;TqP8u2kR-R7Jl2(*{|6b?dy>!I4ewA^JGW%~CyACqt@aCl_A|unl zV)raEARV~&-TrR#u;nGgn=2saYTBSdgBZKZYyE24kppdllwM;AHRjMIY}g&94eyoPO%?;hH#Bj2$zk77tw$!qZ9H3oU^G zVX?nVOzIT*VM*Y|jj2>fe(wvOJA~^{U@yr&)&v4jlLbG3aH~9d#Az)~}z2LwhX;2Zw;(?OGGWami^1U>pl# z^!{nWj<3qiI0e`3oE9y*M&-L_YYyrJdq>BOAm^8#KUZZerIVd>G$NuNfA)6fc6eZG z5)y{G5ARs3W(^9Rurql}#{YJ7bW8;f-@1MKT3SG~Fa1EaY9P$XFDbcOdFI@?w~3~D zmJugT=y`bPaB{Zo-t9|sTT_9VKaaNtS@e8j;!AM5w?{9HuD=SrcI~~laudVD!}Fe* zN14N!Z)gzK6a?aURMb_bRd2DBKQ4wnh>#o;ZL&sohW_J16vjbKqwk>?O z+4)%C1=;as4qT7hckaCS__5Kp@wF(0AGWHX6ACp}KV%Z&3}&{u-Qb3ta=p;TeA^Mr zd=r*`>_{AG+^m_RH^K4I#pj{*Gs`Ec1{}1Gx&||-Nt-q|T=$|q9y5M?U08#Kc`etS zbeKC3VgLlTcMIpn!ERCCWiUR>r2VjE4ccz04fcOqdlRteh=7bIPd0*TYuO$J#n57< z!iK9e`S+wvg3I+wKTh83)w}ne`%H_|4`n;5>U<-87cbcy@9-PgX0%37mysh?r-mD? zF;*XAXQxJ5DPQ&e>x)XGKX0W>F{r@3a-DEot*j>g6|0ZK7y{f0YDp!5q1>vm@N5yE(JcLkq!I&s!p@Ryi# z_cul+^A;{#Pax_4*4EaR@BV6Z#JIUNXOJ*w>uAx3w;cI;To1eb0;dYw3r#mi?il-J681{d;v zW@b&;UExcglH0wPt17SBcHmvnC&0LMCJ|$Z)bJ`aAwY3(h}4jcg3OK$(=PR@`pRC^ zF>1YfDFYu`#@N+>u+yY@a~~?YrMA=Mt_B~P%qiZyd2{}U4=Vm+YK9tLPrQW}YmnrWReFy_3@|M|#NibL!oL zL78^@_U6LO!s6mh{D7F~2^RP6NrdKNYX<`iZGq&%Xk1NQy)HCgUzFlGvsDty%RQJc zs?uJkQullcO0HC*^SDAUk|1yPx@H*!2eknMn!|QU1;dOXv6lW^Rkv2nho{1dPJ@Vc z?cSaA0Cm5HnVDJeK&O_ZB~g_wwe46KR$gB2S93Z=(O7+bMMxH^%I+%b6AbINBWpBL zN+FVD@Sy9|@$*Z3BJ3~4)1G$~XTVtK_6vFrMNNIp{{7dTI@OPFOweH6z`YXzeB+eOt%*6Uy(AQ{|jBYqpN2a=?HAcBn#(#+OpE&l)&s;zSkRnOe}T zCaS7|eD2!^N2=1%=wQQe`)NSU8Ap30x>gQoE5E66n>O{rO#H*cyHh4~>e{u|%-G;( z3CGi{t*y6i+qMSmbj-MM`cdX-SFb7&vn}cI?p973=3c7C=xYg^pn`*gQ*v@z(W;So zG_|w}KmDQy8$W51uTl4PdZD9c&+di>wsGUe3bB@(nenKkPT#ubAvv6Sml)0Emq?V6 zv2EyG+-L?wE}@CJ=93I;>d%nTp7H9Viz^2c!?Oyi+zS7Df2n$%+))iQY0*LnoEvU? zeTv%GiGA*xnVY|44toXYPm{%Yt0)ZkXf{Fr)a^7Y_|xalsf3Ki9XhBiUi`76#m&sQ z)=@2aYu8}5t_N)_Kx4P=p^{(OL{HBVzz*xlB}c=CMS*;M zd&k5Mjt=v+8q2h^ZL}6LMmZt4+^P9urS`|U1-IREI#czY08u)>_lux2?y>4 zdByK*yPaI?t>dOxTW=(9>QSI|ZMwwv?xBcNr_xc`#K0>fM(-+i89&U;&8?AA5)}4z z9B1AQ1r!Z`?VPZthg+3E)HGJ;)4O+l_RYqeJLgB#&1!QmHTCf1f~6gQz=BBQ;FV?? z_H$eLJ26p5u6n4kL?hxPzklv-M^_h@nQq&*Ht@ur{rc_OvvzykzI7`No@7HhChBaQ z$?Xt&?t9UL~aS+i#L^XApnJs60f;>XXQD&?8`7kGPHn3;`^FxBh6;{`(p-?2y5@Zq~Q ztw*3J?zZp7{Y(-i_2Q`RJ4W}~bvP!bvE;q+UG=D&=?_+}YNl}To*zLF*ZNx>&y7o- z@wWm>n=o~1Gp_L`qK1Nk$d{6kvYee|--wR1N!zyaL+wbbKY(iN=Fh+3W<`+ojhU?b zvli&NlDzZ<3vRm&U01Ze)$|mpYC=Npxb=MX`$2ZLR_|I+^0o6eka^!(-))=~yRMa6 zS=-^1b#Pf~HB%VoR@7W!RH*SN_2%C^hKG3hE-$#Ia^=dEQ4yw{hYoGS(FR6)bjfqr zn9fZ|Y3DVzy;IZI*B>%$SQ^3;!ur_Jqia+*EZwk}t>2|f7XsL5_2yJV-=|#|u2*}i zmzOR*1|^6;ZTq7qPhPThM&H=DF=XFcZYyRfu#dGiAQjhVt#yJQOesdowkinDfpy`6K1qw_rFOhBW6sqD&6D9>ViLZTh;K6SbRV};u7hd3)>+}Vx^R*Kuu zS}7QBTz>nd3Aq6+nKIGDCTPs{t^Jw6l)4Y+U);D;Z``N{y_kdjG0R=&aZ~7qEeN0M zsYqlq=jPU0HK{f!dTJvIDy1Ho`e;+koVj!TKv~LDvSRvi9P|5jb-wa5q?%B&QPey~+BEzW#u3F9W?Ry8y%moIb71l~F{;m>L@yJYPlAJL2fZB|XtkWMt;^`1r~@dm zouT(c-^v(DI=G!2Fk|uWs_07(m+ZfL?PE!WXGCN{&ag#CEQGJqF_S`1W4&7BPkG zJbd{6;>^1CtU6UD+00$53%6k?qQF!xsy-ZdcZjRbn8Gw~-aH@OMZtnQ6;uIj!IRb) zgryRr$(`$oK$ovv@!8?A!3)V@cVRSBIvt{EllO%}xA3al-v+o){HvU?L1{nIt3AkG zOnm&C#I6_TKr~^}7s@Nf*CYiBP@3C>>c>V(;I9;BR5aF>2}3{yDF= z{_fB5X+PY(F@s84;Bn^WEpxgRZjPVbDEF6J%lAd^S1z1UykLLyTC)xx)8aJ-eT~nH zuKNDuck;2lI$p_VmXx1XO}oM0!7WP>AkYrqJm5+%Tz*BNIeV9#< z-jg;%UAoGzb~D^9PhQ{92v$c7cYipZk#%m##ZX)cf>FRcb zwGlYHyV50{cN1^Mj(pgD_R8m%796?o)#O6keO~!x)8?j6n-MU7?w4J6D!Z+ld+1He zkmuvQixwSl8CoZC-;n`9f3u9wyTo4}DoMwdyc^n&O#b4~!W&62WqC$#;h)x}_=&S7 zYaCriDL*RA#2#!x`V_KDf`-3q=$Y3o>o{HbaB8tzgI!C^f;2K6$eFb%U=J;{JF(7{KAS8o9z3oexv;d6!2-B_x^I3F<*0*W*oQ{`uF29Qnx3f z0?h;tZ)uTpx_s${?%lfsQ=L6|q~S`|=xp1$vz9_B{)J{{Ez(;oITE?ZJTGcUR<`!0 z5VtEHJ6r75X?N;a$+VD#$)0LaXR=)rpX5ZF#}+!~rriN6@n;s;5w6;0rUVsk3zS#6 z9f{N!G@z%yMw?z=woNb180l)XLHE!Kga3I($5^Z)He0fc4e0x-TTdMakYE<}44_#) zud&|M9uvnQUX?>68j>!aURWMjynRT9)!^Roa{mupD{-1Q!t+$5$FOI|E@UU@O!GYH zdCAxObNMOez6u=sbP{5x=E@bGtCUx%tiGGMX@qBTLC&Lq4Apu?(RvH>;=UH2cozNS zmz&YDW#8PiHJ=>Yv~sUQNQZ+57UfQvy!7bEn2^OGc?a%1{jez6@5r}$rFYBTB;B{| zm2{!vYm1QQzJUkc%wL&zXU(Mp(>%_ETsrihr$44u+3UCu2M$a=y<$<`zPFz^F&m;~ z3&xTcsY=+2f7+Jr@gQf-unQwBa_%!qtwFb5^f|16L4h;7Pzm~@)f&S*s6&R{Fp2c0 z3dh1#^<5_m$QfQIT36(`L+dh>eP^>R0-0{_W_Z z!uQ`kWE~9g?5gN@XZxy~*grbl~MuP&b1dBYcG<+XR;xzup^(u9$BS6+M^`0Rn<(mj8Yr(WG@ zo+}paoA@ZQ->GI_-#U%wt6sMoN(uyNP+_Vwu4CljoH?#lZTE(Tc9P&%iNtT-{P~4J zS~pS%UH{CS*_rpPwr%|V2M?~0AiCIARc6H<{mplnq&2^lt*50c$hbQZvS!RXX1YaFD{#u^31-X zbKBfj-#m1t2Wl^WS2<{v+u+HMD{I{RX1V3-8K)GPDC z>-*;)?)&+$nQettW~&9$9~9p!xYA80x$xApOKIoMEj53BSM|T4v-;V$6ENiD$ty@O zh8@by$Z?v-Ap0`q)_kjRBdS|6Y9eNekIpaYvi?%tpCh3fU4{GNM|qjVhFir;Ba~Og z-q)?$f2W4~H;b5K4i%HN&wD5jD0?%cSigSRv%BZMjZD`6FxNe%Y__hm=k!Bga!a#R zZ*?zv8T;Qr!^5fDsr(~S5ow*!%<9_Z-v9124+zD_wAWSEFb<7c7jp*8gi;yIz=6hZ z|2v|vZg8GXLSx2v79$Ups?YHo4KO542n!H<4rmVD^9JU;H7 z2h&*BukPQ@)|x+8^+KjsLQKhJT_JJ(rACcI;XEg1Z6siv!#yFO56)Wnucl_}}~go4#zb za^7AJxp+4xyLf5d#p%!Tig%Q??MQO7Z3WUpmsG2E?Qa#27DV59cWdBTyyQo9ZTf=4 zTcxAX#u8i?PUV&7zke-Xg;vWZD9dStZQugcjqgjWZ#rukdoM5kQm}8&o_e6e^r%#- z4T`)rw?Esr(7&YnyydMHJPyeCR1q>lYtESw@g363UG_znq<f*74`>J2!2Rodu*Zu3VWWO$h-d=jvzT&`}4pa{_%D&C@h`DDG=n@_Jzhdl)(j!UJ zA7@n+CiLa2cz(iQcg?-G4v<``bV`mS-HnROxi2w?BG2ZcM+*v=_Awu}{z7TEnO%2Gupvs%Y_P9Q0vjdulTd1zRY?|A(%Tt z!ACOKocX&=(9ttMZh*!L3jEn)DM1H*VwSprQGXJqoUI2hYX7V3*vKVB6Ga@B8c`El zo}Jf(nz5#XL&4}%YiiDzWgIsnU?b?6S@F2N-m}#1|J>4`#eWX^tkU^$)=!gGG=osv zNGaioZa<)HhS-8SDzw&`Sqp_&9i|&+`bwit?iM*65SCW=32P9ReH=&U032*a=aj3=h@^LiL0nO_{M;=)V|K<^_4FD&$7v9tFB38wr%Z%CwkL?9&dkuez+N;g*~=C?y!nA z!Oo3n2m#ZW?2U48=yKx3iTjTp)n%j#`jztVVN0ADR8A%vwHMry`p-jcbB#lLLB)mnrBqzEKis)}8&s!KOYktfG6H=@$m89Lv&(F92Ics%g4q18$ zCY=m*@_}B1wP!0MD7iYJFDOzkNFdA+HNlX8B^i&W+`AX}Y?r>}1&^=2n5grw*U#6j zzhF!glH_UXNQbvjPotfO#gZ1-lzm zoScfi+N>NRGghE$sl|*!bXsr_fGPMi`q$BjuVZ{vfX;J0Rg9>=k^n_*f(FiGKGURi z>kZH+jvhUla`o!^;_cTJ!1hu=yf%>)$&=Ct!szFBzjuwh^3ra>InP$H(KY9;v$dF! zm+Y;|WR$tk_3PJH1Eb}1t8qUgCFsnV{xXo_?W<9xF_%S&p*`LGg%TfKU%feC_T{^G z1By-jJL1T)S}%09NyHVpW4l?iY5~r#qAF(49<1ZmE2mr2)F6Lw>2^{V*0XLP+NLbNd!IIpbX0)U~UJ% z#KJAhWUmp7>0(@78vuO*$^IEI>mI&<>fwq{lFa%Tk4nyk62mlQf3)|cKi4W_hKh;` z`G!O&=-Zp$pxgK7VLL#rVQFP`8B;*ApRhCR=g&ts=w36$dzdGF7_i3`@O;^@X%n60 z;2H|PzP{YSnY*WzefqRQ{Q-pW^EIB!K8FI#@%W5&RaDl4DT>pekFRg)?b{1d&W$uB zn{@{NqE^#@9wiq<@V{y*$ynw+8?*)w9%p3K;1|A_FL8iMGKmR*C<8S(g5A2Q~QNq_8Z)lhX!8}0&`hHuzqFYtNG`2lb9jzYk5Mwp- z^trFD%U62VTM;+EeqXBG0$2z#AIj;b<*HqpJqN=AcZB?(xP(WdqZ@+Y7^^o&XxL9C z94l9@WMsg(?*H#C{|sxXH?(Hk*<86l>R8(N$`H zG(R%;m^FKLr_P;gV!YXxmD>&iOVzDc?=q~XcOm=ruY-&+<`MjxOGH8h880BimVWt? z#)i*pZvG9Bt|VcA?EZR}g|V5L5>U(@qia6r@}54WO;c;R$$s|it8NKCil7!lmcD85 zhdDze(3*X-IUk(`knK29FfU#v8vVKL8v-t@{I1dLnWO3}Obq|wzQZiP`g9qWJy_RM zhqj?18jBz0<*84e?EPs?ScA=p7;LODTR( zE^G#W4n8yZ)Q-!ufji-7j#6u!a_d%ou<+pia~tN&uF|l}4*%e^FfZaszY&kj)FJ^^ zKBT`Zaq8gYICAXd?}ZcQ7JPl+85tR4k)D1u@}t|+oV)Q^+1mpWTh?|WV8PO5e6odU zV~CT%?EB?)10SOCsG)#smP6n<^1sr-d*g5^AZPwgR!~$7-nS3Od}T-gCpAi_{MeP! zl<)#<4DsYLSLP4xBmed5^$;<>yPez6@x*_)S+ExnC2m0`54=biN+sT9tE&8;dEyQv zqL**qZUA)%m{WCY6%i#xgeOH^$37}3{}FfgtWdPjFQ)k%q;^oV=46e9=zKOjG zJ3(V&$V)n5rgJznv<8!ix(yrpj_Lfubj@QVyiS_7A@I;r)9}?9Zb+Zq$v4j=qLhO04&9FUx7u z9RB5pg)QZf$9PsOgOKFDa-{=ROEp{Vc`}?lSg@Ay3))=F2&Ni8h{eTBj9T5};HvG}L%^$r0A`~x zj#7sMp@pa88$FkH)s&LVPg!ut#*Y{BAM~=ld-uxW#3pRR)t8-~H?=${=c!8cH8#vZ@{=1QWI37Aw!19 zd>Td|6R5U67u6J_ICo$pd?RR&$4{JC%g|`){>PVAdy%YQoyiX6t}3avr$;c9hMUJ}=6*~EjoAuAM}C5CO30xcuNd=Ie<*Gf>vaG<-f*YEERq0r41Yj@mG{N z9@B_xaAlP{2Idqm0WZ_U{JM3UHumt7;iKg$m>QDRhRh>i@V`nKqbW)|CR=&G_wGc= z2k6*@_V)^0ilfassiua=9j32k?mB+Lgf-QLNug;9$HXb$Feu<31|En*eBf|*X4XwK zu?c$66JE+fWHmt4^?0sO8ps~0d3hoAKE~L7E~Jm-jPN*zEPLOYmUe$g$eu7&1S0<- z99fmx*!IbSc@{Ejn+js}~xRHFA)8=|3KaBhybs zM+aCbYeKLg!umknVqA+3$8F|~8Z|4?@JdO;T$CD8Hc>%c=mNzD(#G4wBn^siXkYrU z2Z>3LohX|LHSoWD5)xJfN>j*OOEcu)U)E9hmn_T?j>nzp2wiV9{02BlD6XeiSk!^3 zDS@SS?NnZ2HVJyD(RI<8!Ou}-k`4odGl+a3EwQ`ph>?HrMC}K>_+z&;g&00%#*9Y! z$!j!7ub7am`#Bg(pEpazm7(uAOA8CXq@>|CmsYjGk`SG{ua8_2Q6u?uJCeH=ij&` z^(G@-`8g1aDq^ik&uLQ_aEts6PjCeW7}wB8o!5xSIcwclWVyn^U@=#FNExS==b79{ zIluI6!)6C2u=UM!jM(D^+2P}Nh;PNVe6QRY(K zY}mYc4AW!iQ-Ki8X-!k|@;ogsJ-QJ_iSf5;#%ClZHg+_eL?~-7^7B*NR$Mf!tF9c(5j0;B?#k4emf%|y2e#n`>^H{Y_cT;XPwh%j59 zwf>-=e&A01rVG=5ago;&3;9E|FR@QG;i%6>j7PWv~)c)G$NL@2ks?He>?ZHtPE z6sk+%n3x~7TO&Ul+_lRrD6h9fA)mx2eit~sH59I0yGHt1M>PyDYMq4Mddo9DdxY$` zF-sT|{GLyElXM27m@{V%?MlA&v}rQyUH)uE9mlw~41}oA1+M;tCwbYAa%XQS19gN@ zOasto#-&v$=f>6TG{zfitInF5jcICz;GF}Pgo#`n?G!C}Eul<7Q}Cys1hdM}qL(Nw zEnV&JUk}#m%G-f3@u+hH5T7?-UL=V;=e4WT{hI%mqii4fr{w}ckl8-ngA|Hc{x|O2 z*<#k)5Eu<2rKW9&+!5&>YOYZLrlgcG%3Yiq^@kp%4>=~x;A)zwMo&Vhnt=qQ9^nmIlkZO`Sj!SxR(_pIU1o&ntC+-f=xxe3cVy8dC4@1yf*^{7VEZoH>^MfN7*1J~nEG0DC zkwuJV=uTOk7F5s8mZ*cSQb{3r@7~mB&pOf*cIA^wj-hpIMc!C-^sZ4FB>!eC3Th`9 zu)=DXu}Q39)BiTn{Qo0GH^bE+g$VQsQ{BU`Td6gM)3E3qvb`rn0=_waQ|DpBR;I-3 zlegvxBUvUBxL?(SFs}8B>iYYmY(FQ;XiCFtv`@|;5D&N5TrZt!W77a)pQW`me4sti z-y4UN3T2Z!mg4>Ei|X)-_h$g8kHCSZ`bF~4Nk?aIy=kASB@YknBiW3>QUBFSmpY$LkX=yc~%N0I4zYZbk zz^cy^%nO9BN~)sdmI)2DAJC*4*{nx}@JW(y` zdD+h&Ztn*Om_*xt@xy>Hr~k?xG()n{&%h3=*{D%qr{`8u!e9wP_*oAhSNN12I_&Az zj%PTZjJk8DreP(@`=$hiMoOD&7lfQo6PZJnCmsd$x#~s=_rPkho1OmO5{J;fudXiB zE%Vj=mzLLNJj^&YyQE15v$5HXEzO%R*fhQ5W8Yr*=Uh3F_2ha+=G>xulfI2-`0CA@ zmngXZR?3uQH55>0NLK{Ysy;#fQEqP9<;yi-rL~Dkw;vM8lak_xDw$iU!pU7vOOSZd z3;p~iP8+9&dh~tnxkfM$8s&v^u_VvPx*mbI0b||4AibAg_+>hEYSxE1f%sduYj?)u z%rGFh(2pOze-C@+QQY^Wb(}KmHZyPB-7jNz$cR#dQ_Ze|HmYOQBcm@FnDQ-+*9MVR zU&W*DFu^5!?1HdHD7aG{Ana^}vA6logQASH^k!gkUu?C*m56qG~3Y`ANHg=M+mw zSIo_?wNJ(;;ZJR}s}1<9Z}yPoB~M2KV3_vG7G2IFmj(KB1J`PdFFqIQQi-%T@GqzE zF9jPSQe&85hdw&DcO;ekxBnML7jcuZGU2B~O#bocEXOzm9e(6BQWTR6oTJu&?^5{y z^v4vvbHz%N>oKR^Wim5aOVhBfwWVc))MpJEp(8R1io>GM0m3TCW8J!SQ;>*S-gzA# zu=p=~o0|?=1&%U$$6L+ z3L71W?g!0&Y;|#6bcVJ-0@)AB$4{?zOconrke$3|=#m{v)Wm}3}EDO4pW>5ECAN9cTtA2;W zGFIWIb}vhdw`DhBU#3NejMW>1Y@ayMi{=K<0UR=R`o`^*({nR7D6g+cJBAQcbMRol z;gODCU`fk-?A1FH8r*48@V z^y%&OUbDqOKQdc*OMq|uKuCq{eJ=hy6}rsp4{`G7MM?z%p6ioP4o|SvvL&pZ=Xbr= zzCRF&#Pr3}c%^WqaG&0L?}J zki95uv|L_Y@0d>O4-9R$_Me4@QCkO1@%qY z=671h9yWUyYL3DN7AWZOLLiV4382ZHF4D|A7(TiFg#tW zh$qd005o@HpzDBfj6jM1OU90jM4aNd|={9a+9$pEx>1N}O?la}o`xkP?so z_C`GgLpaTK8cpQf-D8{kk2x7M_9RDAPp>BDio#gLP2eG-_M#D!p;lxwPeMp-MF}Bk zuYZhiFIC_yP%7UxS-(nGmCOvd+-{Iz3;Z-W#oMjQKciFCqtBu=A7?n@+d2W?E{7s| zQKDQa{q)Ixt^R^%kDn0PNqm1e);7sr9Y_Rq8#EAAsc0hIa_*Aisj*SDc47)BgICn1 z!FT7ePVD40_EG)q&LEI7?Z|)o){jI6$n4Vg=%W5McmHUE#(2*k(3a?t4<;cmmF_Lr z8{RNNtU3zR4-U97ge-f9H_nPzqXM7-;rgZ@8hv-I?ZP$DY(~~H)Gjhm@GU!t>S0yY z*PI{lnqhi?dH+znR9@8kVuLnC3-Tk6{8FBVfp`DQ2mfL>Sy|0^g}fpP zvy;~f7xcVI42)^mU&Rb?gTn3Om&^_1;tl@(Yl!wl79=G3MMXDjRpBCMxg~2x=$Xq8 zmyPxyH$Y}BSJT0}+t=*SD0np7Ua}}LwDm}@;V6AHS%w~M*iI9~n$3bT#*_IJvM_+Y z>iJZr?@5Sm`V{6GK?U@kaKzU5`PDfy;L!T@{{#v>0jB*Tv0?zYR81!)_pLT;PvmtfBj9r`u3hV-u?^}YU#wLAH|TT6e~{XTkc8J52J zLLWF_@L)v+aD)F2$-jk;$^i)}|FC5fMU*I`@w~7Q-Z-H@s=-HqR z_xF(nLe@u-g08uGvD0c$AUfZ^AUCnL5M1QMQ`I5_Pl}=uZh>H4$TYc&G zuh|d2{l^zzCBxdHDa$5)+(R>%o?d5o$3VAnfee$j0N;UjwH~&t4?46z4UrbR^2`eu zxod|!WzZX>>v#9O$e2YQX&tq@*krsaa*vm|$Gk{vFiEa3m3Jz`JFDfB-fzNGLyFpr zj3p`Y8O<2DpPY8CA)BFIob-KBgkO!!{*AipgBg<(UH}O788HN7KJx;bB=;slVnzV! z_xj@^xE&Otqx!TwqkPASk;jlFYYP+2>7x-5jqlo&e*rIS<|fWw=38?{b*(uo#?-=M z_+lfU52mtS5}F%?t6a|G{8rSAD+T8k+_s}%2p1v)x9 zGs#845dKICJsGpe(1cvNl-=xNgH>@kE#plhOnGYmK;q@j1()VfYg>-E;q-s&0z64IL&B&F zB3jHIIiGF741}}hi*^o1%<55Us{u2mXlu2T8!uXc?yvARs*m?5WO;qH#$~-+$JWhI zg)JcT89b0{L>qQ$Ps$jFj*NLAsg5s-=ioh`Wcg1we~+j?c^lOj?dla`n-=iGA3RkU zMmk>tN)8xT^G-VXlpW(?Xop4zNl{&6_v&vVc39c1uNDzKxNmnk8N;StB(VwUjrAWjS?tud9c2_h6j5Q<`A-<0Kh z%F-Jq{VFf!7koDW^~@CJ0TivB24Q#mT0EcTq58vda%47|qjiNXCFTHEt*y6^CNs9^ zrHGlq_O;g>l|M-xLZ$@8tQDBv?taNY{V9JWo6@gAmqgt(lXB#CtQCkuTZ}H} z1l)l+VkbJg*-PErvWshV?{su7B*rw(qa=_ew#pfuXyV6DoXB;etxJc|fi7K?671>B9$)%|{U>@*7+5d{&DtW>|At$TkU zv?H>Tiscp}v|Io$*mKC9>Y-`Sqf-MI5cUGJsv%q;0+6$->lIpT=t`SwMEY$VBr;04 zCA3!;M|*yFgOyG&A*`i_&5(Jy3*-TkT>#idFIzT9n3%jhQnic8y(7Y}mqrChfm6t( zxvoi))P)W3QW~q0gtuIpcL{`g!a#d!1Gok4who@D65pxCk0RM^ZuFy=HoSHJISsIN zQEOZm<%m^Z`&tT=0Ys z(`O7z*09WTW`VGbF(*!(sIZ!7E0M11Ev=Q}v#+#UEqNv7c`ln5hFn2f<$bRG5&Z6- zB^&N}*AMj>I1kn+4G;?11f}^ispZksq2iX>O70A&=HiMjPv#!<^hMrd51oPf;6wX2U5g6;{`pgjSCzCwUB-zue943N1kFOlC|g9IQ%JAffd zePWZt%PamTui*kZQ*Rmf+-KXiCe2P`VUhOjYE3=g3tY9Cbe%k@S)R|jzv6%k(ZwL_ z2irU~*^f$l0|6)P>C^qipNC8Z$HMOgai1i65uYHgq?fK%U9G6v_&1lNS*%zw6dYoT zsi_aMgf|5oOQG8-1P@u#nXjXT*!cE=5f#jD*8M!UI8ZeIXnv38WM-XlcSDuh2+9oO7?!h$Gi53x=Wi3k(!BsR%Dg4i8tHvaqrs!cFy zx`X_%py_S3TcydHIGij{E934i+#9{nt;H@I4#=z<)v+eJCwkJ;cTc`sXWxu&0smL4 z>A)8)nF3Is2x)B7Re?1lm**lPSA**arXWjXYlpg2!T$^3kmz@9TGemm@{Se`&we+m z%$_-6cT2-{$GaZ$%zf?F}x;xq7So!`*r`{H19NE7#Wa;#wIZIr=CO%Vzf1C8s+itdY z8)=sD3X?H8PtEthfsWn!Xfv?>3}^^rPDFt@G5py$!FIAY)*y-sur7Sb<7xa9MkVi_ zCiF*z$>lA75~*N{g@J)Eakv*CWfnUx{Hpvi8L%o=3(y>Gq6#q%_Xlvi-xWhUxsV8OLh5L~Y_w+1#;a!h9n)RzcV{#1|yQI8Q6bjV!FRtNefss)J%BSsg#oNspYqb<^Un#fNZCh?FM&wG z*se2fy;DjsUv1w}chv?Y6RDY*P3ht`&I}3(u?^|B#<=P$q-`-6Ab>p$JcyT~3_L`o z2|CaOqBaGI&V{}Ia7h?)ia!dJ434z5Ygayri9N8Qs@IQB@R8;F z^;T0xFJie?6Bg=)!&4++=vm`mez0OOc5;F+kNWvzAohS^=(l~|KXSCI!Z%byYg5?P z2k0z7F48cM%(n}B)}*OrdgSWoa)_2?W8}DJs(+sF_kU$ zGJ}r{C6EZD_5P@_f3-4wNnhugU!bLo)AqoDKbr~*fIW9GQB$x@baSn>!nZo`v&;Z1 z$OhfIb<3oq_Bqi0N>-7z)Z;ixKfp*qW)L~n0F%A8t$N2&in6d}M8~#j)`p#!>Lhv7 zm0t-|st;^Can5Zwo%lynC}pSxXptl3c%WrjjPFB~*0Jur130s)J)jac0wc0t!zMpF8`=%N>((pIMly)z{Moa zaYsf`DLk%VtGXEQTbL)8y_3FJ3XAf@eiGpl}IWEYIu8uFq8sdN%|zLZTxm?*cSW<^J@ zuJz^|rG(rQ%sXh2>cN#t11k%8e7xM3v7zHHmXl57tx_IFMvaw2eW10|H~*%*A4@B% zI>ivkEzOsmPq)NbGiL?^r&ND@-WiAAx_BGT8LZIOxWqrgysn}%#Pu^(&li$J?~*~E zJ`ELRWo4NN$6ALs;6DV`h-kD#O=?@D_+xf-YtM*Cz8PyEDAh%|4yxzIY%0=vru5+f z)>;o}JtC1JUo=*rXuXWA)T29(x{6Oz7~1Q7+`9PE3-+|M_?Jpg!f%_2?SrO~&)kc{ z9{%7w%XA@#^_}y}=I49M#|+!rzNu?r7l=G+y?Bq}=Ra$QDBKu44BmpBMFS+N@gA)> z%xRyn0WhtOTJ`h4{5}XT=z-x-IFWQp&_|&|vMzu>JXpy;&wR?w) zryAMb4iSNtmKI1o&8{l+l@JxMrq^vAX{Y=_CjgHtR63d#vs}9-u+vT_W;GFvnb`t& zvOc~agNP@3M$DET;4Q{?mFuS3vya9l2j#sjIb88`et%vsLPSLQ z4BOcAXoeR5tX-)HJa)`Lav3?CmPt={Ic>iFvL^ef`1orbuRDYMP!QcIEIexej(xGF zFnp#Kx+#-rfumUsDf4)-ZelK(-IG-6VPzx_K9 z(fW$A^75Wm&bV7e*vGZ+!- z!}1liRy;C6%8%AsW{ISNPEtzsTlCCWxJa645ibEgg@G9&_6dt}I*gPlKYjib-1Np; zTmO1kIw`S3ORPgbeea^%qz{?h(IPV$z=G93*(2bJtY1~;iZ*- z=5GqGNaSD0{ONYKTbJoAvH_%|I0i3BUE0t|!M@vejKPEwOT^wp*e6@*Yy z(@ML4p`wATV|zh+$~c2euaW`g_iXp;YtAf*B&4`N9P$FOY|%4Pu}c?Jnb}=^-WET4 zs?uY@kxtq1AO>MCswM!!#)^HZsV(7GU@H<_FRv2f&Qxa%l+4>|)0YrKIWLbPk7H?q z3LxXU)29am@1RgwgFT)wiRjwmOIzpv{0_oVNni8=o6}ZWuQrG&AK>gzpR!iyw_N9J zJMmuz6to9>MMYPER#3EtOa*lzqfzLEvcs_~ENdlm*(fqIx!z7+xTiWgFne7=+qy{d}1sZ7ic}RF=0_A4t=DQ(gxIt8YAb@u#EAb2%VyW zynY&LYWon_N}3)pAo$$5VN`A6mXpc1AZxIGp_SIo zcjv&kHdn&K%a)0rhbo$eD~(fmlL4)^eO*im7p4}62J@F__H$FPvM!MH?}49}Ktwze z(RgKMW*Uu9J)tY}a?GS=lj16w0V@9Q>+`l+l8(d566@-Xx~~>)s`Kj%s^$;G(sxhK zWu)d}G#WqEsjaE06+Y9QG170PwWcm8SERuZlyY6@|0Zue zFX$|4T}2>&X#C%@N#J*Mplhp(4wwFs=kmX}fMX&=J zJ~MPuX8)43TQJOGX0dLob=Ua$?Kz*XUS>q|9cc}Tp+z|Mb#YE#qncs_+tEId)jDI)he8h9zk6?fvz zn#$LhHZ7i#R?t|E7lfvR?;{Hyz6=e4N#JSH6*nYGNb$51n@I8*{D6QLckgbVcQIv4OGLMgr@uhv>?(rd<7WCJyS$iDy7a3(G2gIQ$KDs8(=(&(;hqJQpKtgQ}Z5e?It0M;Ijt zjK(sn!Ahp<*E*-{qqSpDPaGYXSzBCjuc!1d7?q1*t;yK2`RqFpEdyhU@-939JWN^R zGIYbmr~xP|=m;xWd{QboM~Yl|BM|oj8CKWSm{~Y@k?Vz;C%%2XzK}r1{#Yf7$8G!N zNF_h2>_Po)@5MY3YNj^-J5tF#Cau|PQz0#?yaxE4eRNGMwsGivS*BjI;hOj^q|eC@ z!=3B;YNE&{%+a^ku>!;j#JMtWA#e{U*BwmC^S#3@n;;6860x9M10*YJunBdCyOKdtjHcHzTF0AsbJQuV9uK@Lmo1!fzAhq35Hi&dk;=*5 zzosO%cim4^|3NEBDd&**fI2-C;gvCsP5buk%kCX&!{hIdWkJqg1_KA4^fz2q$}j|a zZ#$b$MkIZ#822S4)MsE$26mY*Si{oJ>)VEfmAz-F_6s(vfRwh;O1vs2oH%@p#F!-v zR3Rd2QfYN{HHBP|_}yYI<8&!tm=KNf=SYB~wxxlbykJ3ZsYSMI$v#2$P*ruz_-E-L zGGv(LIQfu*)1daQJ59+Ga8&k+Nz}x`a2=^X$Hz@3#kd9p2N|EDCv&F;;O#b@;F3Wr zLtTx?e?91|;8Unw6bif~5iCffjFT-j^+W_JySImJeM+Ju!A1j=ghknVAgvGwK%2cI zwU|{8p^z-IOgCY(CDD)4V1Q6Aau4uz$|7;duceiU;DU@3HfeM0A6vj7NRGmf(L$E^ z7)lEC@AIqiEj&RuY0$7CB11Z3UebYk0z`m4B6*yirslzwXFFs4;?!5kd@Jx?scg`0 zbJpUYO-N!wDn|+#Hehal;b?Ck%URH%5mppOSnRT?WlZEPCV&JFl&Z1d9rCEA`12a#tBJ!oekilBxbe^U`k;|Ir-$YTOEqD7R?O zMEwtKW;T1aF3P;c<#)Ris|GE6M1`!uys7!#kt+qdLz{n!Eh|1gCFuV7g&VhSl_7{1 z5YjART#MulHFgBtWGP$919=;$qfK+W>!?@LIku(X56Q^LDARL@ME-T>cXs=wmojC? z4A`Gsgnqzr-v^e;n}YW9AA&)`!>B7>+>R(%*lFwdqxRo6j#6WM=2y%C`X8 zAYbRRiGb3-v0Qq7T00bdR#m((PyMf5@d;{mym@m_diB5tY~O9Rv1~xX(GG+5HB) zs01WW6}=C9E8e4*EX0r#BjayyH)6U;<3U#U`S?tn%h|%$n8#ph(Ot)cH8b(Yr$2`? z^Dck#v+E|yPkVp)L*+UPFeorG5T&0aOcz)6p@q7LlmAck6{cHt+8i7KU_AxL#rR&bjU zE-%1n-2mOgw+Ou$MzGY;9R%qKr`5q2i zcg`?~z5IT|n&4oC0$Ath>Cx3+Kn^ygFt?iv1S?}c9IWIPk>TNE7zTP)lIz0Ti}9t5 z*0=6Ia>pY_CIJCwm`;{aV;Rg#OAEs6k`L6y==9w@@WugG-V#6N-b+^HPOI43+RE#J zVR%#Bh6F2!AM~L&RSnrR0{VcdRi2rMyR})x=16#orL<`EX_?Yt77=MO$Ri zup$tS1ECFyn+OtwfMCR3X2vyk&-hN?yBqBm5R05LpwYF=_Ut1am)$?wL1F-7;v93D z9BZnn_#qII_0f&{yMCz`sL^Md8=|6bsO-!v?7V1K7(W@BG$Aem>mqj?(M3|m2n=&Z zJ`*e^=@8cbqL>pC0N9b=(BPuLHoxE|`|iI0EaA|=KJ<)Qs1~}{Rk}4qnXh6OjHUT6 zGC&JxPp@xZP##?>u4Zy;IDWh!IDsE#wH*ZZn>KA{{F7zaU}5;x5~xSc8#5;2at^~w zTNq%ilafJQ-k4cY^oy+})|XDys)2767mBcm2ou7O_?Ak9Lr@lh%>q<#){%w~nuv0_DdV@J_vZ@S?oxI%%*S8FJ>}uMrzyQYDlj zCwEO;oEF)M5&L>ntQ0Csyox$(wn~&=45lFut6TT(f~%o*SVzKUbuyk-ErBmagT%{A z@j3~OK+WB(-2hV`wUlhcFha0G^b}`&yp&DKKF*Lbl|%_CyR`DMQ8C9%bI{yY6mCch zosfl$tD`~U{iExuLMwU-VzDXcg_(tRiZ4x@)RlF4vHB{bGVyxL5)U3MMOc28p(4dT zP!|DHdAUqfH|B@Ij_PgHla%vfKfi;p8`lV+UinL;F+p3NP(fRWC{(fm)~qUQ2!@KTH~6*y3} zu1D?8)NMnI-hSn|un-}}*-gGRV^6>(D1PCAq0b@LY<3K22#t?RsfDzjxyK3wi)1uV zFKGq(wz0OhErCUy&MwvlP^G5RHquqKI|?am5)fd_^pSy)${|hOfmEv`$Eze!AgCt1 zMnSVVXh;*(v^MP-OG$XqzsCQSFV>)A7}ug>%xACPAdtmh$U)&KDfu?p?;PM6QKoEa zcoh#v6i%({x{IySEmNhcx5;2Yc@tRxGT}GYK|m@iO6|<99}2I?y14HA=0C>HMRm^KD^zeNn>&22g3DcwYz+3>|EAy z-gq#%j*5!yVs8UxB|8zQbw6djhm=|mIR~L|Z>Eua{K6|;oup`zABG}`z|Is5Q&J&q z(cEVjh6&JMHGS1aVit& zCmb&0>z`nC?k(X>bcx(oP&Kh25-df`UiqpbCvbI|e3DXytJX7VMclBZjTlMdt(6rX zZVN+FTv8H5zKY-?AE?IDfTv$yqu(>OEh@y45C{$|T`E8blZ`ufMqtve%@8$5kfD}b zsKB#6Nh$)7kbE|7+^Ap?<1bF7qGKKCG4EnoTel_Wex(25igsK}E3W8Sts{}K1RXBf zO}2di=U5Bzrj%Su(t5$86%7|V!&DHxi9q$=xmpJk64rnLdVDIrlKR9KTvez! za=`whN1dCN%bVQVSz_&hQ!kgCi(gUiM|wAFNGz9szX0VNy>ASn(cn{2-%5oWdJ>Rn z)AW&z3On;sxIA+Uk~X}!tq|po@D?EOV`S^bjT zJ||C>-VIDIh8_ms-WXqpB_o1p&lSX&0+*D%FG89@wRVD5%)$1*j=fOHZ|aPUS{5wG zp{K17F*}jXoc`L>BB6a1-@aH<9-*VI^tbG}c+*la7bEm{lY57MHs*E7JS`VSNdbQj z${^8;^jc3LqyaXNiXV>2e*WJtAWs(QsrN22Y0fKtE%J3!9)yrR{Fw8{&+5I_R#xKH zo#V+Rr^h_D`3%vEn=xgf@wrK_SCVkhZ`xAv<=|5h-ZMBBLw}i!btlJRi=dGZRh0sGr|$pRmGv+h!>Q z!mre|UojC8D$TTvghA~4WH$2(;;n#@=OQckDp{_Uw%E+kr?4{mJUCu{rGhVc7U{qB(M$$!u~?u)^By~4}Cu_ z>jvQ1ocGfDGDnwF(>KpFr6+j;46L?kYTuqcl@v^nD>9pYy?M}8Lvr!9h|B~g7Or-1fl`y=LFDybY@XBu#`v%=y1$<++4M02sDZ*N5tp@ zHIuj_Y|HT4PNRoGk?iE4Jc7rJ=ibR*$u8PZX!aMx0ik$i-`d^e&p-dw5B1^DyO7ji zo?xUZnjw&upaMcu_B3ONV6A|Z5`aO(T5Cmn?SM|8A^ik>i`kiVT|p4vKBv2uqwvZ0 z4Ie%f`s*)TbKEEsi@#exyLij<_T$-rG`yIX1J5)iBTyNupE-xk&$Lr>?Ycky`~jS@ z-jGGl9C~Mb{km|E@v|+7a}?q}02*`^nY>G{Hiz~cjMWS{ahq)s*{~i=Ey(>L(}sX? zGjmr@p77<5OF0-sW4oC5d!D@6@?W{*zwaMk@ZH)jmf|D(u0)5_)^Fr_}H>2CpMV^H5p!nQ_J zSN)LNja3f?%ZM|t>?$WAAO1&CIQ^UdfbQjfdkmf%e|%r*StOK&I5tq6rY!jUveM;? z@4qQF2mHCZB8MU{j9P9YCAMUGnbLIDd$EJ zF@8NQ$xJD48BnA{Ss!1FrOaB`JWw#&TYUcyS)H>cHTb;rFQ>~84-ahm1HnhdbzT?~ zS{VQ8GNsk4SA#7@MvXId_$ZS;c=XAVACXSydpoQ}T?{oU-H-UC)oG3VO9&z&%pp+k zKYTcnV0(ley@ZPz9|0>r|^6@VyLAa$WmxPgT{zZQKOpDzM|SfCw2bEvCT0 zq&E*R9Hxv+FtISpJ^B@hEsP}i0?31{v7>lG`KRVh!qkuX`SvtH!35i~?MPr+3rEIB ze|WeN3Zn*qoADm^tmPEI0bu&Pfr$iJEW|6xp?B_&3JI9i!N;`qUpH>NOONvAyX=QH z6BZKatzUH6>+;G@9}ZG7ZxIBZ!|X=%m5Eer z#0Yo-HjBFsJJRHQlH9!61tDt;1guK7OK|$qT8}b77JC4gNa`eTy(n^BZAO(WZ5pB5 z9n6We;{Gr)%<>v*P&+hk(J_;FA|1FYiP9XyM;RSj{iC$A)Rbts(pFT?+`4UBM3jY< zmF|}P5MvNRRMl*O7uY7RJ6RToim+@A5J+Sm5jYWvgv=eOQP;HJnV zWeI^plfnE-Bbxc6OD?aD-Lz@{HzPLmR@Q9EJYi%_Z#u;-$iUaYVT#et&RQ_xW6_IJ-c{XQn0Ng;8?SyVH0r8zQ)wQ-9`^I{6bc?5U8LTz z)#qnbReRd5ZnW?0Dh`Q4V9Q>&CN6w>-VkxO`kYyzAt8F((*OKt6@8Mr>)}I(9NQH= zWs@`Wx{iM9`M9GkEE)qINQnVcuO9ssKuo_=UnYNf*p5ltFZOP8=-B0t&#CS0-c4Ek zHGbvi^1QvZjLZ?qi+{$R+4JT9KI*=coSees@?+KlwMKF0O~R*#DMYAn5`NWTzC z6mw>Nk=_*p4Zjb+ck};?-IBvc^kSfw&u*NzIV@R&3-AIJ-&ij%{oe}>h3G^I!o)u% z6~cnGlqJ#uIr-{(6SetOY0P!}z{p`N*^b?>DwIRg^Aev-s71_jy8)_IqY8!kP##4_ zirKP0tOByG^^bp_|GbLU4DGIvEC{XYFe~$Ari`XYq9aqumLb}KU&3PV8I6OaMCZpd z>aVfLs?bOYvMq$;@ZlZMp$V|Z#w{EYlt}fAwZwx{#CI)d`s8;M5XC4uMEReDn6iR{ zEv4^<&qDSXP6jnKoW;k!lb=5ZatN_UY%P|8Zr?tY{FplKIAsvZntBurJ%w650wXN= zI<`K+z`XlK!_{^3=7A`M&Yk<->kN|TD`bFQEA{M~3b0`5=$#d-Qt}!3io=lqC*hjt zQj8uezCr*_*#pX*jwp8qej^XBMH#{D8iU6wO#V|&Pw<)HAIiX}JojwA5jD69$hv^# zU{7Nq&hBsv@>RpblDCP!uq+s1Yj&Al%`KoHA=N-VF-%$V&!N`mFx9(M`_Ft?w}We5 zCWEh1^=e!$i(>`yJ_tHlya*2=YMQVp=_;402~JBc6INAYqo^qa`^FTKeqzej3+QK& z!Zo5Z^=L6_7H(k%Xrg4vQf#!B^MnvwuN zD>7lxYSpRdgcqym*J)FCfvG6W-%zm1Ir=5zkP1^cIaqTBV1il5E)S6N$=ighV~ z;gK^0@77q1fr+fY2WLgMPLST+&BWB#&A1#?2!r14Kzs zB5g@>4#40^7zwbSMuOR>9%^y--aS^w<@Gw#l<8^&q6}6<(t8$~43H0O{adl@$r%RT z)evyAq9-LW-&FsV==8+U2ciWopXp5*UJzE8eGf(hE(Xa2M$!r`h(cgT4VyBB zq0D2IGh;c93RLVC#MzB)nPo$3+UL1kw*}c0zdD|dIO@xJq2v||Jh{6g*Ew`09129u z^$4${N&VOE{GoNfHNzG46pWvyKdP7ixKxh5Y4wrq+cgdLk29^AhMx&zB!`^#^ykzw zB=$c-m+C;W0j@8i;55xm9MWyeHR&qkvCGM!O(xT>f%s*yS1XD=bATOF;*CysAE*k( zPsJMbx#KCF3c2>DnAmRqE8b*xXahId`VE9(SB&WlJu zO^f_$QuH#VPKb zJA;oRLS-$tT23lwKnO%&-E(DO4lR36J<$NjTDD6Hay^un?(pl>CT`rarT+hPZ=3A- z8^#L1R2;(x1&u#7H@_Z?UoOW?Phj&WE#Wf=>6JuODv@ z{2CrscJw_c2|%}$->Ai6#Wg1`F0M?ox;;@P3g7@xW#+5vF;W;qoP>*324y+9d`DT> zfh>sbdNflEk5zmu$4PInt;hL#Ct+@<2BNi_?Fi}F3 z@kzt2>)-FsZCxOKom;O5GMiKvuwKeIu2Nl44|=?8$eI>yVSmYAabv z4RtMcVlvVyffBESeUSP_I)!6XKmW8wZ_=+sf7lA$)A;x*1avdZ6!dA$HkY=zMT|;ztM1n>D z|Dv8k;1$Gda#>uDkJ{Q`BncJNp9f#z>&@J^c*8L2a_kum*IkwA?_rN z?~reIXf1`E*|oRAKG42VL-g}0n+Q4H0F73BR~RxS1(m7$?AdE6-CQ^Y{?`d!qF@)} z2Sqj-;rh8a8oK{ffbSxk~6UAI8ABBNs#UHyB|+iM!H=ttZ? zdtn5BmSKr4XRYqXZExX&pac=n%QS#HLsy(`@yHj8MaU>`+z4fwi|xF`M7M|5IoDn- zK_2WOndbSW5rCQknxnV@PQZhpK5tTB`%U%{yd?P7p$n%q6mS?q1&ej!d&*Q|b|r%Z zU3vK+UZSZbCL)~AYx6L9!k^zhX)^~+t0DKLP7HFO_0Xo<T-tZri%JrqN4vgTe0`~1qVXHI~=!m}s> zZFK)EKi$?~Mj#a`Lsd>4^7-Huy=!liv*kxcBJk6co-5Q*`2!OO#mOltVOKdPLIz!Z z99ql85Wzi-H2Xqje-6pcsxogdNy1Y@&?$TcnlckpA1$5?3)7Ug-Mv0#EWb(J+G><7 z^^zdf;sxZp#xDIWzgiwCb*5N_QMic%A*C{|MLmo<q{K^Yx)vc@F4 z@oA?|UzNIv!hlCnPpG(>n!5LZyqousQb-LgW;6^65Ryb3`>Va+SI0O&kubZOqn64H zi9i92j(`wPR=Xg;hDG-vhD;gX8Rf=RAmId|k80Gi(|U3_p8IcO=Im{QP(1^!onrO) zAyg7(OyDq@(H|)S!v_-=8>JY)4bh`qp(xr%*T}CC>m5*=_yjvcq;6S46B4Lk$gVtn zss&D&BLo$_Jz$+fAI4B1)~l|+m-tK{%#-C`Ex9(6c)onaz0IW8okUWy;IH~deIoK* zgsU=9C`~D_Bjlz`jfv8Paw(VgPKsu7ALwf*__s;oB7_(CI>gHR`1?7KqlHpi{?Uas zjh)3Yh{2yaL3QCc`$N^|V)JGV;4N7u-u;>TY-O(DvgDuje>PCo*U^uN*PEnm)7aqA z3peFyIU4CMi7xve+|McWn(utHM&oF@2I|tbbo+*#kL54jQ?|RG$ph$r?(j9=QAu4K}n&#L!pP2#H*T1hVe^ z5-~4GOz0Dfy@k`VZ=c**OMJq)k+zjOlRJp?PUm5{n2x7f8`<*-Z6>LU^jEin7%CwL zC{*OJ{5J7tg)fn!nh}AA2D^@%>TD_|M}s|Q%PpF9t#$Rghi!Q9f-}pe8qtKKJ$!G^ z5~z(+K%73$C_)J_mcC{9x%PJ-k{8yI|Fxt5#L`sVK)N(0POW29JwH*^%$%tsJ_Yo| zi0{OMxV?Y9{I3{|2Gn*~nPo5gl*qo*gcT*zmlZ6cq6 z=Rf6SaFW9A zdY_vi(sAgH1+gYBcGRjw=QZF%tQnY`+EpX6lKIE{vRekS?&;%&&n%cq>bk#ZZ^G<&Iyf>~ls-BHMUdtjqR2WSZmP=vaaTESK5A2=oJ( z>qrwU>!oSea((^8|K%+j>N`9PIE&rpn)3tM{-9X#`s)k+DF76j@=4}XO&fx6yU{m@ zlcMz6@QA{NU{v%C>(jC>?e4y+e*d_wG($8-d;FdPwaK&=u-B=lK|Hbm z_t6&$*t@*1gu zx*fH-TZTi`ZUTW!qEP*CSW0 zC_AjHKrXORYub+7#y^TeZ8w&HEr&|HioJUr^d z6AoVfg>3^0fg7sJ@;PTl8=1@y0)|I56Fo1E;Hx6nc<|Zf%%R4jUfHJKeL)4RxA@YL zeM))gxxn#}#D|#_1Oi$x-TBa9Q>z%!YYLhGV(XTn#x;JqW9Wb#HeXI$e)r~0V};mi z4L{PQs;cbc7-hR5%=HT?LyX9k$J*SN7!HqEqJHU1>+T3-#jc5ufy<=WKJLeQiz$1X zvw0W;0J@CkVu+U)Nu0s@Y_L$!3Q+?ha(dh{bdab|fD~U~rYJ&RPL@;voTV(b?(k0T z%?mc(!s((N7qS3MU-pNA3ekv(5asbJ)v71Vsxl^gEhOXR!KNxIV%D>8;X;`!MudRh z-S__3Qm|zLl7YL7ACzdA!2=Yw%U@TmFeZEr)b7_Qx-mLPQ1G}{7UPxelDGo^66?NS zW;j>S9uoTrC-w3LH8nL45DOtYZNWa0G^ZOgk_a162jZyPd$OfN4rEbf;S^UfLE!~U zV5$6&@zH+q?u~5)f|TJaF}skk2V^%Q_v?gkE8IJ|lbM>mACt7>*Bb?U;;E#A@8e{%N=N8#6%}NeB7?0o^(oLoi3IkR!5G^ z-7*nO$GLM?=rOKEr_65? zZVFdFKxRD{G!$_eDAaa_;{HUE4ooHO#&-=0Q%Z;Xg1rx_&lF1a-Eqh({6S>YA(J-WyhGFvna)3Csag~!^&2B5U8^2*7e$(6q3mUA;R*KFQZi!Q( zZqG^Ud+A#}3e^z)GT~rkBjd;KnQn1q?IN=}}?pSL6Ua+^C58#d&SB8Aa_can0IzZG%m>O+rLRlRJ& z7wxM%dK-Jafi~!4`k(m^!>NL^nG+`R%?MV)q0lzMUk1g+X`%8I?uZtL7_vrQ5Rzi~ zo=hZ$0x63eOMHaH{+j>3mAB-MiSs~@w!79IL*=}q|9YhMDsksuCWyBBO37lQqk}hD z{&jB~Q;7@!y#C3q8HErkXOx35*3HCZ>wG|~_^Ue`U80kYAV}L~o@^>}iGV9>(XGzD zQ3@X|_L$pxbxqNwca;tguD>6ylTr;y<@eZAHD2Sdnf*`RPUwT4ZRKnKcT6bu!&`w| zfHAC4oY}N1D0}W~dL`z|{nWnMdjMex6o0^e-r-m}G_eiCH_>s4C(eF%>4l{KO#o>r z%zI_gu@Rz+L4zEw6{_AnCvRPLem%^5)V{^KHB?lmA2(cop(Cr5Q&|m#?dWV17vvct zDS;a-2%QgN0GCt#>EBg!&V;tV8f2oVmT6bn2yOHAIG@-4%$nFPF;?E#p~+MSJ-S3m zU@`$FrFauH9)rM-JzE=oCMU6+uI~eEdk9awv<<%+pvY$jLmV;uu-Sfi-U_RcYwh5p z83Q6E&sW`35msrSHIC;&5!&Z`aFYi07-v$fFzR&o(WCQbmN&6i$;t>h#aC8Zwrtsg zSS7`Z>N3^OBYKY;B(8R(l4)Rb5A^5rb)$-`q*?|z4Jqi+l5fKKjPgkv9X1}rY+<@NK8R04Xs zGChZ}F{WHMeIDYW{TGOS3G@n39U`<7cRk-ywAnZVUIHqa!=|gBk3_(HP$bw~UVIh$V$x5N#_NeRf92n58sDvYDDqDdLZSIJ8V* zX5zBhskb=|48LAlFjj}9`;UMo0ki12yT>TYRg{h2NJra0#Kn!Hd*ZdT{cz3bE()51 z`;m`~w(o7_DBBUS;G-1|&Ml=LS0a|hE&0@6`?@*N?+eeUnP$JhaeofUeYM1H+O(9d zeH9_Cs(LdwL{sebd5J-6Q^-^JFVk>G)p+Cg%U-kS?J5tw@=D{*$0zQ1osc=@4JM|4 z5f8SvaFLP{nFsY8#D)^fKt#OVeR+d9vuEpo-xAZre^L}p1l|56eTNJ=V{kd!n)Q`r zXjx)w;ChMWU~35_S!|sJWW{gOBf~WQDi>3hNS82<7K8*s0udaZG$9LO%?CNLHh7?K ze~dhv3^sfk?!I6_Gp13b9EdxQB`)>}Q;+S@!ciHaX&>_`xLpe~t&llT-3CR2)GSK1 z!*wI6BLV-=l*nFD<~q`x?^@$f_~7K6mK;-QqQz;Tz3QyOK@9GRk1;V*^c#vm&=*Of zRE{TS#QDpLTZBc)pMLalxuCg4cYMV?yS$1dd{#x@Na~Lwi2h*tKo+YX=dNy}9Vc@U zsGRGbxO84GP30ojWyZH;%xhuP5Lgp)PEN-DekS*(0^Oi7S~I!6D~7wGU1u-j z)MT5_cEyL6isK8MiB#p7-AWDEqN6fZh;DDs*|V?u?&xcZvkTi{{AO@evMHX#9d-Tc z-Aw6R-|*UNJojA`S-9X{xHlmZh(IQyhT;uXTl;UF&<{37ys>Dek7?XivRf!yz47bk z@XKuN5tobYWwU6nxSwIK8RMIztm`>zmMme=QybtR%WBolHLhnnpBni2JDbu%-#B$T zuqArkJ0|lAnrz4|?LWq-Q?wk0N9U2tiU|N_##)Om)@aB`PWrze9`9rnMMRJ6cI$uw zrd8e2mzJmVbXNQ`^-o4*M8wJtfh$-=qVOKAmEsa~VeB+|9B?VNbA}?^5}wF;aPd?5 zqkeoVjTZMoQj7#%Cd%x(Y~9$x2bCt3dHOJ|df!~nV74(TfHLg%MXjmbTK9i`yMW^B zjy3ui(koF25z`f)k(<}KmSq^_J5<%reEG47Uylr4JUL+Txfx7t?`|^u`tvqB?-uTw z+eszh&^eft`n1v$BDJ=6Y|$9dPF5p2rL1pdGHr>s_ZX_n$j|3y7$Bq2|ya>SAzq2`~VhW5J2Of&9U42eK>0X+9?z8Dj#KamM##P^`TF1a; zMc+f?GVey$NDLeVrV(`_$Gq(MeX`&SFqx#9 zeLp`!&kIf{E8!T`6SQ>2+oNX&d38`|FPMt67#P6g-DUUGV)JC5Dj2qaXS;@7-oHPn z{OaRV^JTLN82{4a*7L6z{Ik33%hezEzaG=?`#*=FenFIv-Dz%fsfG1N?JQk+&Ge?C z!lKhrdGoa_zdnju{WG7#Tis2E6)7PQt+niCKU8*6;VCadGSIU4jz@{|ckgB)S~w21 zr_rlmf!a6!VPfcpvjU4k*1$p2J&d6=rU;&6v|>Z&QJshd3u03Su@wTQ*JIBXKqC<% z(Q_LK9Z5Ps1%wdsluJ@+D#Sk_FtujwkaKMFPllloOWG#fW>f1p*_33_p+B$ky= z>`&Y$_4ldgKXvNV6+gc94?I|^{YtCorH7%PaVJWism`}HA3Iw9?J82iVz7t&Z|v4G zn2~w8wx)0U&&jip=E-0c?~X;-8;DJ^vJze2LDjKwHoY}U!7YXN1r5nZjx5XiWYo;p zcXozx4C|%R*smoD5}s8qHJ)JJ#0%4-XgJ2`sa^W?v8KGBF=nG<{QZsESd}a}Cx;ab zLCw6da)t4S10qhK*#ZQdW9& zyUfLVNCB^hdkV*T~nEz$zlleC#=IH;{(Z z?WkDT+1r?Hg{JFVbfIAO1&G2eT8gw^;hPuX!ryO~2h zQYrgA>6iF`W*L{aV6{O~GCCf%Q5Sw>nos`A#Y2mioa3`&y#JIC_58Q1kOKGxP3CiZO$=Jqb`6ww*p5I&!4JC!b~s#(x)_$}4~xoZHyEZMV)XAD+sXUNE5%2@52v&-sjpj~^E- zZ&!7f+aawmXUD7h+toLY2y|iZl<9mj$!f>hDqpehTLcFgmKD4_imNOBzL34Lg9*9X z1B2*6!hA7_D^G`2MjXu`{vECN`G7aq5SF?z!zhch*w0H^07c%bQ8b);C3vbB?&10{ zd%wMj!z6Zbh`0pdPubhIFndjjKJ?c&l=_OLDPN|TIaM0VnM@jcuJ55rqmWiL6Iorl za^=d`VQS=N;cH2cv+23E9`u`Y3y|@}%^}ZcozuT*9+di%xZ6T-BYYl+pCTE7o2B2j z(F->+Ue=7i1N`ds_X%wLr4B>PxZ{mK`1jF2lvk@VAt&4r)Yo4D#|A+>0B$Hm-NYa< z+%fnDZUF!GdfK;qr`#MKaRLwTX7fC$^B{rP6df(&CA7=X*1I?N>Yfshxplh?y_UYT zyiD{A^w1m+i3f1nDf-}@w0VDT)b2gS_FhnchyUlwjrD>8+qHbiSJ!QD|J1BNEEE2NvVFX{qiFsA{rd%s)S2EE$OmffSIR<%uM{dEHR<{G#d2CasCzCjFxh zVVs4l`=hSwAEO-*=7<(oR5x@dLJvu#o+*GD71}}QnOd(!ll~5l8_BMxL z3yO(RFGyQT^C{r!{F>HTYtg^5ilLuUtM9gB#wei&p-Qc&Q@{t&6~Ps^ z1WigR-HH-w!=#D9WMUbZ`957F>|8H24es^aSbOqlY2P+rsj>nm0QSCk@zA5bUp5cK z@)z=VZhdXP?v&`cyj~@RFjyi1G_V~v?g})BHbz6BNw?N@9?bMSm=8oS3EBShw`Mojn4pRg4H^>|=Y1wx#>s03C^V%6N0s06 zY~y0`IAU3IhFj?ixrr_6cDI~g){B>WDTT$A4TQ3RGH<`nM+?3ZQoIJ+dr>%8N5AF1QErq^p**fXG`RZG%pwyi^ z+t0WZu%n4OYoKI~gJCvV+e(OLW3H|CSak-egSgJG7sYJZvWELvOyxPJb}}rX*D?=R zU<{FLp)O9E|N7(|qk4Yomuvs&#U1@SAgaBlrU()kL6xya=}VCnx`Q%Gck}*J;l!#9 z8^;gVyJnj=JgS4Hrk>Bl%|Gv)RgJe|Q~0L1xTANL8G!u(7GO%x+306z=%^fYZTOw$ zLaoITSrT$>&^lS@a6RTLF0HtB((dn_oT9GKojiZ*?Q19O8n-)vaFo`^iH3eg0 zM<`54*(kZib%6-|3A(M6>~iB3#}lz2E_k|3R!=>$bz|%lXXm5+j?vpSC;h{vD((>X zG_DxnNg|dWxU{~iXri5RjP{#3OPe0Ylg1nuHV&WPo`3@~l8?n!z_W?1jtGX^2zAwH zt}XvcLFWh>+L6!UAvl)b`AJ4JEMoKtb1h&OTf5a@2`sq23!mu3nXvClS9k5h@5x@l zYu1RSP;hF%?gg<0`roaBb?>~)jHRK6jBe8&U*`~Zt}p=kt3VC{D_-_6A+j(W%J%9g zu}1+F;N=JzRj}bEW-O9BvDD*->Jl(xDC1|5$nPa$O_o3qM}%%MqWZr&VD!3-~W7;ruinz2F2x?=D-Tz zC)vayNFX7$AP@5j+f-HY!btqt4cfhmy8_Dj2^>(a>tL->`Yl6u?AkS{$9O~Y(hja# z8~hyp-<6XlOCklNmI|4#1*v9a2Sgy#S}+t6dkA@y&Qi(39o_Ktvx>#f1aKk&f;gwH z#}PdNS!%L{Ut4u`nSjITl24cTYS_H}Ky+rud$EhEygdtVQd^x8&J%(Fpk(fU+gsf& zArdd`x939Sz8{|t5%4pAo_;u}WpK^=$FZ*}#?7IKZcim5NFov&;-pa9SRaY|H*7Xf zdA|3o%K$HYwq~Sgp{1}D1;~ZgScgFt^^xAJG0No=N%@qk#hG&p%+p98rDM9Ko+~&E z(odUydX&cKfN=ZrIB!BrWB0X5b5h9F2H%C4BkPE)R1lfKgB@}yI@Isi-=nSoo}(J} z8V$ruLn*2i#CX6FJ2p0t&do-YQH-pPvp2@pHg(eclF#4itH)4N9DchSNXi6sg=k^< zHr6Zoz=4qRdxfW_7eQ{oDnLd~D!bRc^U67HZkfK{L-b_FYMXl2tQYk4J)IRb@|P!F zuaL}_aaZOVAE=10+@N*1e0we_ST<7A3;;eSsz&CppSiaP^q45E{_wOzQ;pt%R9`4i z9~wj-?}Fxm(p$!=i92FCCwf%KVdtdJ^H5TdY>Hlg(FCdl9qp#8tMB=^fb=992yx@= z*|Q15>L}>k4T=g1vY8zeOHPJc+$fjetCIe(aYkzyYO=y))wJ67<%Nf1v-AvU=D|%- z%jTcffXwIQfD3BZEuc|1&l`zHqQY&#f*TDc?ON;bZ_V4>B{eS{Cl*_qF);6{eWS3t zS{_l{5QH3oFurY`c(s4Ax%2y{j~1$_sS$Jc?x?v=Iqp+-XYwL3<>W!ne0!)%NOBM< zhK;xU2XE@&+i$uu(1dX<5lC!}2zezO8u-E_!y$WbGo+}3T6Cg|OBBE$(+e`_#&uOG zTJGaBD>1U6ovU>1G=pM>ME@-^4%AGuGkT{pMj_)d$kl@KUcK10=#mJ9?)jF6o^O1K z$(35cH<6#*(Y7KuljDt$IVfH>gX!@^if|D}F-xlkzm5B#N4^e`H^ zd@K4Ju>%6SP&b7GcdN-|G>+meit4Z$aem(AiN@xFa6jO0mx3+!9`895Bsc?IZVtoj|~BlJgiwE~!5J zM>F1uyV06gZ{GCUt)UWnv{Bx)rm=Q;qfE}P#lDD?%6g>rC&l^}XF`*Sd5<3bb8fn; zb+^`(@4b8)AY&Yh7n1_-<9%j}Z{+9Oz0YXADQY=jrU0{`duS}hkV9)_krL-14bi9U z^q{@^3+68QL|47X34a8o0*<2~liT^ixUj!Q4D<`N|J8BJ;t@&c=;4U4*-;Y+- zb~fX=9PT>*Rbyr1_vOMan&aEr^-=p)(S`J5vp6N)EjGYoLV;Z*$U>iB=LJ#Iwnj%S z=+t1#sI^H6UBMlndbP5tU6JfOLc79@XE%I!hS~AM0ImuVYUw^Ogui<2GiSpRKU8&* z`5T#sTme}dc(7N+%{6X>x_d$Unu-Ay>L{@e1#6wjArn+qfF0}}MP-8`^$NYoC*p81zNj#-!cvLqFgzrgGge}x;Fi=YaMOJyO7eoXTeGvG^Oqyn|5wF3eRrx;wEpd#1 z@c$&6w&`{O-R`|#cR@xf(5+!LT|&?Sj-sdxCE-$s4tkNXj2j9Lz2klQ?P+Hy>!lf> z%PRU%BXfcj;=LM(_hgqX*ZLvhXAomsyK6&%v0A*J09w$7uR6Wt603uEw0Ls!_zp!Inp2-(dMj*Z#Ni#mSSI;Hd}>bT z-JOfR?Hh+h0+h&5S&Wbc=kd_s?YZP>#jI)&XCu)HVj#dW=N7zhAiT5e4oB)Cbl<6o zeewf<*lhy)A&w_P3w@qsvm?tVyu-+Vp^rVij5k?^089*sJ4o;-XvmQrfo2hsY+uO^$1NTJuxNfb3vP(vT!s%?Xbf4aw zKA56#`^spjinA;KJ#F%ajeWhLub`**nZ@=Q>^rFF{{0smLlwi4jxZ7EGx4$l7+c4v;uV;2 zQl=?yH)e7)6Yx}lZ4?=7vISJ4W|nyf;t#K=pVEE?{^;qoZk%5{xws8YJ``;|X;Aa!e_LFHrqyBWPy2~>=NjFX%MlUZwc8Tnqg~Z%Zo#otRio#A zZj~I+`@j#MDJ_ErYdvR-&pZJ2yVseUV+)e=w&%h)iAx8$8Ui?n0z|SFhhe#u+ul~g zsKPiu!jW<(n4=J&oj@kTf~WKT^n@1R#q{mqk4kl)Ts|&47&!E!#NP!7kBsk7sJv{ojQ2 zlRyS^WKiwdvpr3^OxQUn-2C#0gTG;=@+7v$MoQ&O^7}mvjhXu`-yQ4u6=*cOZ~`e$ zfam8_sMDxH#RndIJFBY3!*9hZ2;Cc&3&B}bR$L53Dm1X9ncqZm_^x)@bO4}xcAY-3 zpDpRDj`jiPs{W}}naLM=xfR@QOQZJNUKVUbgtKXB`DM4;wtt@dhyr|2|NeG|j?Je^ zmLTj+<`;)inU()FTe>67Cq!=zQc{osRSk``0Qur9N-)X>JyOu;$YJ8FkR5Eg=xb{S zHCfKIeKv-d+?!eT>?lSS#QwMrULZ|ksQ1RISLqx`6XhEZA5JaJxWwEB2Ad)c_ttyT#{WJzJ`ASix2t+WR-o62;FTuOK@92bju63s* z{N?^*TnmNm5SNx(MyGC0Y^&8XFN()?rd^{9WCka*_X7pmD2}9G)^1o8rpqp+Ip*!I z=eD2CWI3b^kPRMR3sh&GIDUNJ2aBJs9v)rk(55%I0)kBIwg2G3+>p|jrM)fIYX+f6 zIqB>lJK5DWI`z^&D$ElF!hx;&QE73Z@@fYplAnC)KjnR=p|_S+TSn+9I3E}sZs^(I z5?_hA#k`QY%x?0>%0NY2dHf)+dwTyE>*^l_GeN#DdTW4WMli5f+<*kR|I;_LI1VR1 z*PBi=OGibF6at3Ub&Vl~cPR{AG24Pb*ltARh@w_IbPS~RsuXk0C{E)Kg6WNwnE$1JL^_ZU*n=9}IvMIk%&b9TQia1l2;XnI7A2^iK{|y0vllL zQZV7kg9qE2tiHC!jk7J*)Oj)UFQK(?V=f-E=S=8^<1=$qSc4V}b`>og7pFmtqeNUt zBbw%{kub2HE1JZx=;%51Tu?waB8^KI`{6?iv|rM0RSz3;Zvx&9LOU@K3k)r28dKwp z9(fuCBF9>`qxq-If@Av`BoNs+n+2ds*+(3L3S=hwV+Ly+BDMP5meO(t4s5(OejNia z>*xxxUca&aKu7rU$DSuXQ0v+>j!SZ0#_8R$W-BRnM+>9z85I-Hc$p|aepzxa>1m@^ zV+v75DQwRiHvBkvF7hefLClB6-8!o~&6r_R+M%#nhlC-CP=z`=$5E+=ei$cQzPESz zy?=FII#Sc)B{*Y$)2Fb$Q&biWt5U3i1I{+)4Xm_8%q~*e& z<2N2Vw>~m#y-_Br0&JK!*T(nNEq{0y8bMu<32#ozHq)&EEVM~R2!qza;v00M^*7@u z2}M-~@9I1L9=|xvom()c;AnL+9L{&M-ppZ?B(-$e`F|h*A?@$@MOnA?pMwt<)IZPPqA_~dor^n3`@Z@L$9Jv({?R088(rqu9{VZ%;t^K3#g z$dT2TaC8L9WdpsId$DB$q3)o4M|J5Vus9=etDS=aRh6oOjnxFNZ}$NlC96l2#3yi2>3?%P=E2G2bDoT?M`L0g#H*(~n>h0TrP)_WbL2=I0lWgWTcokD^XoHXD zc^qK8G#8~a^SR5~)FXT?@O9*jnKM%#sv4;VX7u&F(P*Al?;-CtI)ua)-nF6xz-Vu} zlm6U0{%>Y!cL4Qt9{uLP#`j61x>X{ux&){za+$Xe&zZ&N3>*6M$fMAr?v?KsL$?&m zZ>lp0awA`4GJPHd`&oAD$ZAInd!d2ODBlFFle?izLV`ttUNny z-&vSwh{^jkOb6v?KmZ7B)hg}`sExPwY#LI9BO5)={5;fcq{sL~wUGa~04;Ilqb+Qa9j89jI_Onjb}+yJm2IMI{Sl|if%uSEFIxNHl8ta@+%BMQU;?%c*Q^4hM= zmN`ppNamBy_oH)zvn_h^c1tTid??NDa#Fo*Gl26I6lVx~1(y~EWQqSU;pbCw&I}*bK3b9 zLAf$+gKKFJ4YF{p? zIL#0g>S2DCP?%e#cHaQA2V+<=c zzsS8FCvi1C(KFb?&Z#dsd%% zTCt{JMylfRR*tzRW8H&Zv1^3U)3G-7_Z;0D=raVZ3I9|mgDj=FSJ!U*t-oI~OF)}{kXCzUi(4`8ogthGcxlO(?5m8WJ7$!FLpnEeCjQ_a3 zz2Qx!rHTyVc^Y#FATlc@hs$n)VtRJX4po|LG$?&$HGTS4FnQ^*iQh7L1)RCBJzc9~ zr%sn|-3n}WrwAy|bLo=}U+p<3ySfZ(#X0%yXk%G+c1ZvJiV8AdB5Kv6xf!w@F|osL zVQ04NQdsuo9JiwfV>~>%8!0@-!bnCvym+)KfD+t zAcw4H9b`P$^9Iz>R3cYD@ zObENue^}9GG{le8-J7*O^ciAh z1{o#$moJ=YlZG)#g%dyLPPlffvsFc}hyf4Nmo6%q{>K@rL94pKs>rtb6b|s<73y4S6}=Gu{MG&eQAG^RQV|14rT(hR4ydvBK0;U18=h zgLUyMYN|c^d~#=ZP4nk%#2y8t&sFIywGrvXfFH64~E_A86|1fRoqFXbK^tUg#+ba3-iaXV{1{+|?^=4pW6wq}X&^XJVO`6Oc zeX`JFc5dwwol^BZ*GorD&yD&7T6;<-P21$n znr#|BrcE;U>Np1A(L)2`cA>&L@}rpV5I)%ps3?C0-j!tE*2x5xRl8F`K8wkx<}d>( zDq3_I+JYP<{HAj3LFkdDOP2x)jfyBKogbhJO23Y*L^;V_@HRA zuL8sn{*R#13?gNpB@_Fnu!V$7zb|1C3?uT>w1p?*sYsu30%X~Z_;JFy7MoOBFVna! zZil`MRZDeOTl4Y8%#WuYl|`pLN-JOR^PjWz?c+zKdE|XE1L9g!JyT{OJLeJA{VCF#}9emG|olGKM8k)OQutFFa%*({$ zfo!`Kn)_*c6{qXe6f*u7YAFTi2oU}XSk#)^RITvdYROkN5Q#&hMou88i^B|dA|iwT$M$C8IbCLJ8wl0nOO;tG`( z1{GVTj{eq=QLBOi5DslbRKcGwRthU7<8$Fmpuo+59Ei6Apv_EA)zQ7ZerwhV&m#kE z*NrT2eChEZ->q-GcLS#BFt?Ldg-p7g;uXsE!L+qX;n#+2cwnkm#7Ei*od}-DS$os4 z=jG*rVgiRRl30CF>x2(}I5W#drz&#sJMRm2GrOg_XP)VH$M2L+K7ly*c<`1)Va(AI z*5y0gU#NH|e8Y%?oR_90iLd$L!^;2Ypz;QS zldY0%YUWIbCnz_Xb)g{hDx9*2vFhW%y2T+O*I+s9 z-(AHLpAQcf98Izhez>+U_vgoisymJA-=%@@A@J5$paTs}TV;cTCyAk+0%EO8^pLJ! zC+h_uVHI~md>O{}3YrZCkg*z^8FR*6OM!WLRgF`Y{_Bf$v_z&KnDInE3hV5$EIH)N z`>bzyHxK*o^)|3Ngw?+ojZ*H&;wOd`oY$U_4cxNl_4gbBBHLx?;!DIwv64!;@j96D zOk%$fFa;qHhcFM5ZPEJfGZK>T8J_+2ExDVi@x7>(K5-7L;1$zMG%_Glg|1((K3#5C zoxHl{>{7GC`sL1xm#CaMF$04-`4qh8Sy>wozgxK@m^gv&L<>MUvDjdq^FTXhvd+i- z1$kfN{{B%`cGM&>787%#l5qH-|1QTQ&-xA1?t0=21}(~onJN#16}^5IR~&S{A6QuK zq1WzWO+7&DLvUcAnG3fQ2;~FIol%FEnw*TrsXoGf_HC=;SS8EMp6PEPMAcJtFh$sPama2Txj$d_)H+WMLWsZs69? z&Nx8GRY1br0FYTSIE6szDkJZ6U%xM_`5AL@(Dccv&2;ZQbU)bLM63I{y#0xxuYOMX z(JL_i;>V-+&K@~xb3rRS4Hkx^Z2XB1`xsh%sco<+{ppbybG!F3^}H@T_i|N9=y5FA z#Wy#6f0qlR0(&jg*6_Ws)$6-j$1RG+^}P=Gj(k5;WB0SRt_OPf_E2m7@kd1W^+EGz zH=h4;^dBEL+IQ&i_sW+Utyg{dIO6Ll9OEDq%1(~~UxJ%zPp~xKp1dT=_YuTfN=Im2 zQD1IZ=M0)^cyDKv{g{wo5M4fPH@5Kxlxi4so_^#-f__ei*lv%a*Xl>+dRX6m+JF4r zlHv1Kedriy{87#7LuhbteUM)9OQAICtZGxSwb8s9Yl99p7P(WLE1ElPc=_gyh%2xB z^G_>^kMNS+duc|BDL{m$2jUy8;&){|*B`KKwDpV42789r)*j_!2n9`iBBUv0 zpIsxGvv6nS{n#f$tZNEV$|2nu5OJq@*!5>))Th4hpVlcN`D^==Z?l(da5ympZTMx# z1_+`stWPd1ELYdX-XBacn>vo#IN@_eSVq&R06&Xdm36NlWhVmG$sn4G7-VqchU^Gr zL6xZFq+@ejU(pCkOK&}uem$1Wteo=B-B8gG>5-OMm|5 z%=0y7qaCe_g6~ATRQb*_4oaPD^C|t*c!l5uhO-vamb$KNLT555|*KK}We*lr&~Kd(25`k7_gWwq-a&GO+E`<+eRN3?YfnA+^eWK z?YeB5(O1=POyT@K?s;FoW%0M-kcnO$X5cRH2o{yKgh~@0QBOf)3HE@qpZ^uKxKpy1 zsmi>)Uk+q^)m-aPv>-%xqs3vANL*k6Vq_Pb%U;^z-Xvr~Ugs=V<1Utm`+j!nHpSFb z)*gSrlSB-M!b{o@V#_^62w&|3uSERdn6DT3)m|8F?y7kM#F^IyF>r zb8dTo&Gf_l`zH>5blrDp7pvpqok0dEsA5SBn~RDFz>gp4{e z?Nx=L;Xk_aA@5m@N{z{N+v{F!mAB&K{Q%?6YUUq8vF78C{<<$M7=1+Br>B$}&z-&S zUV=XcNAh2JzKnF+@zNr3YvW&qb^pMEA$8@%|+P-l(ZeUD>ZM+&e}m0|yNf zKk^>e-??E1Cm4`8l|h~Iq4)xQWlLO;!<;t;`P3mI>=Dx#WGE9*nwQ_1d_&AxKQ^<9+?I!ijAi=xA0wAMuaIfz$$z`;M?+& zapE0i9%rqE1Jdb{E`ysgIugGQ(YxZpz9XRbJ@LF{-X^^(qxtX>g=rffnRhmPGvDxP zOi7hRmp+sBZRXp{Drrc>cAXX&y0gdxEa*>ZDCiMrMttHonCwnT-=p!s+wl4e%e+AC z+l50)^K1XyEe$3CUfOg{0-eD>))#lQ2(e6wS8GYVJC4OLB28l>W6aNwH}vEU&YF>9 zRN3vuqoe)5J%~NDXwO&M=_2UE@*Uxrc|=Li;4_s27Cn9$-Jv$j;9>9NV&ETpXrXZL+Cz-}>7qeN6c`T3e8{b9 z{+Va?`Ygu&DyNKDg_>Srm)x^0uBWdvesIe?c|h1_2g4Gr))O51DkIqLE$VHg=odd| zcdaJ`K3vT~-x@%g_MYD_F+b(9?-b2`e@u=0QQy|}R;S$RWmxbcCW2%xtJsIHet+n; zK95pVG)G2n$bEmzq#PHROB6tyCvQX&rNf&u8Wv(BP{lQXJN2Yln(5uG9(uR1ihfgN zafgkQTf`+r%>3YGsv4=&1LRv`9+`;YW$(TK*>g6qVf3?lEbUkBkdS@uoW08ULC0BGb_H^{N*DuQ2 z)LkkbC`E=wvAcbXlx>P$+C+H_JCcyFM?pYiSxe7ETPImDNBCq-2=?s2z#*n9&}@5E zlak1xQ{%>my{d(`F7~OopK(VdzR^l=n_s`?bt{3u;Bk2!Jb3U!ZM&d8kp8=)Qlrpl zAp55@tzvfsSZboasYWSiJZVzM-z#HWe$G6fU{w$t(Z~2{)nJUMgsuW9RfeGz6|T90 zR=^AvM70VHs+i-Zd@(f8W2n3VeTk^gl^`nPBpVdJ7BAu;R=+rd00BKuBn5iE&?vvK z(0%#~eJ9tPO=U0PN;6sGv-t=5A^G^Tt%cOb;q6xMh#T*)=X9E>{hed+eHQ9wV{j)& z0dWBYJ%gN{^<*(PzlbdVk~2!>qIO-oo9^UKXBL;fi6qL%E>+ntLdcbL=VU*8FFO#n zQH=JcFv1h~5=z8Di|-Fa!O;Br^g<8Y=6$^^=aqgOqX1u{DZyCaatT@7rsGV6D29_x zpB7aL{g>3Kc`I@a&67;7kF@fu-TQT|>(#K6$D%SmX0<>2rfkr7`ZOk3)3P>h0D)c@ zncix$JRkDB47HyAn;dqo#>%a0%+#E)Y0-d=SZ7}89ipL zto9`zcut;Y`DK-rYSx+lgZtSRQ1dp2s+-56dEwC9e9}2OwP>xPXfc`gOQJCGsEFRt zr&VLkl`As!OLRZETR3$H5IafvdqzrvrCh1h$Y-UP(18WHhc}a#U_TONZ`0SNW_hbm z{H-7U&o^V$_;Ve($h%&NL=r4|in$@;ii48;+=#W_ zzQdwoOT)v$pQw|4W<<5@zpUC`BS?pi)OCuZ0c}Gb5WY9LsyMOv$AcXbKed( zn^$6$?y-bu^^9-DqibW4F*aXTQ3|m1#$I33&Ox#JjUV<^t1JBOR{F19=<^>JV6UU$ z)zGfXDst3)w3hrktuXD}Dc2z!h6?SjQ!%@SYqN0F)>t-Z1aickLG^4i)(nzJfU-3H z)$UX+>*Nhq^SfES{F(dKOyl9kRW+OLkf{anxLQ!qUWVw5e8qx|F345aClzs? z!#}`m|DMz8uUcExT7R158hAr>+4T)H!i*2 z9$w_<;EMi%fdyuHBOEObYpdL>_@Od9Jw&hV7eNO8@FYskz;J|$W>7nt*etVo|>++&s!66VU1;>^So=*?K017*Xf_G zxj%V@`8ZX?i61~1BbGc$fh!`aqf%qF+oX`ni5&tNlXZ3s3|-)9(q`!=3xx!~{U#FEpvpt+uj)NxD>27RRkuY5e#% z_WRGU1siqVeH>An^_mJ)lAM%LwKZR}aDUhgpSsl66n;$(?Ew^uK9Tp6!iTskjqBnz zBE9{E^z;%GS7ab$aNecEm7f8@2s=o&{7M$q3m6AAS`>%yWRQ>~u8Pl&i6t?JQ5Zdn z7>J6vs_~PD9h6L_a>$rCtdO-!NZD8<)^6r!&|+_yJ&+JfsBjGt(3cL6j1>QLoF^u_ zxI}{=VQ1dcPOItw9tM~=`i-frZii{50ZCYP*&G_Z;XntMrkjUo7haz`nEzjAf|3z` znRj-?@D_zv+2uu(fzzaa*X-b7L|0vb3YHVJ-z#k`Z2UGiAw zmok;)Ad797ZMugRAf}dH=YA#!Kh}cL3|jlig$DLGP3?Ks5QxJRXL>^a5}UphK{Bny zuZ^3fq-u1$a(!0#*SyV@tN-ok{dV)x$Jfsh+r>?Tg{0e9qt27Hrkx^$ABTjB)uhps zDFLO%jTf-Xmw@*tS~EeX@>V2=1Buwuhls~L1&u@o~ zGXV%fuM6Vk7ZCN)bdl$U=V=p*^rB9=Pjb~78@H(IW+yGhv~7>9-@RyjzNkc6w_(Y&Peo^HQhkdY3s)a28+}A`f7OPp{f_$|AE?Q!_kO|d`7Y;*<2L^M zF2xdx(TzVp3lBgR9+t8ro{8{w>F!65F6uGGD|mf)=DJ@38S!_-HfDm1R*^r+KY;^j z$akOs7c1E2*NyV0-_I5|%-c!MM!??|Zff}oOA_{o*Eq~6sWA2Kct;GzO+!2+{;AHP>u)q=T#-!FHS~-ogE~Wun6LWdU;972_L+?!~Ime6Z`2swR`v`H#4#oPK)m%dQLfY%4K8du-d&{ zQ>s>}JKDS&Zk%eop-a@QN7fUp;_Y;0I}T);YfLP}KnU?&Z+-nkwPTu@03y)g4A9c5 zsC;223p4~R0Sz%UifBG9`DPPSN1we5#+*OpzS8x_=NBWUOnaegc=Tj*s}vpI6IP+l zN6ut6u=-Nb-hbGwcn(QahI&_^UE^sKljWqzYJNB zii`s1}PT7_>n`8r^L4XY}YQGO2iF8{WD`&Iak$<4bZo&Xf zj1S0vZB>ol$=XH{N$_iOQo>6*ZUe;-C{c|1Kv4{HlumGm#XL!V03;rUIQ4;5bnmZH zop-o+@9HzD&retWwJuSw{J`DMkELu}S`vI!LvMxS!&f(cJgz)as{O9^>Yi7*I6KP_ z4$qaXw?_XEljlnWYr~wu8on=W-2cgX*s+Ppo`hu)Zd$3waZ4S<#s<0Igbu+8N*|u< z&lY<%y#wRSCQtTeC8TW5W{BCF?glJuJPm?@QSX)-@y5pXN8`&zpO1ax;Cc1N$f5m~ z>^pPB=F7#{DRJQ?>XTKEe)wVi-gDlQ{-4VaM(fk}DcfXJz2Q`m7cRrM_VdkRgZ55H zaLbP$Zw_^jMaeDrFEcEkpTj^~KzzP1y zTfWA-bu|&fwd}_gS_|*}3LTTY$sGYv%HDm=-QUfLOL%E*U6H<9`S50)Tb}3hN85x1 zubyM39yU}C2AnL=zsq3E0&)XJ_y!mnC`ZOU(y+fdxweoMAid6=^oWNt0K% zj&@MJd5o3bvUkws&WVLEFOLZ4ZBSPIq!_ zR~^@nw%eYh&Nu%2qmQN<5acsnb!#0R9R{Zzls9ExyB02RYf;7sZq>YOzYN*42D$-Y zniBn2e~6M4B`m$USQ;G}L3_N7a9hmp^!8a$h;@cy4%t=&{Z~+9W|Q==xuE6mC2%_z zQ1x*d4sClxP@=Np56(JG(AeB@nJG193iK9U7XhOpmvVMj0jMdKl(gWHi zY2SJAHXO0nZ_p!~g6mVwCRsiv$%l2sxV7NJK1 za|?{<@8;emD(-?wCRe5h)KYP$A{ysiT(^4tw-;fc1npHPC(fHUPwXLG9-LA4C@=EY zT~sJ~aj@)(FLHy^-x>R zA1b**I&zY((3I*H4UHOQ?=~cVGxectwA?p(gPve?5K*9&Oyb|Uu!L8N9Gv9Ij;0&a zkCpzJex~mg!y^Ol@z~p^40#Z1)n8Cv4AjGWyL!`lV-8-24n#)o2#B!Z(m@jz^9tGU zK5cVff~UC$tz&)Z!gsW>nfpJhrXOKVTSf6|AeIxZo0!l z!_x`k;08+>@7+18@tp#) z!P;kb8~fp!V!I&oL9AJsLpouo3=#L(v14Q1hFEL`hb_k6VG9l=MQh(^$!&+c)7VDg zHcr>_Y8akTN3>UMGWK>d?gxBVxKH zO2G$ys310CJeOuuB1bW78_$ns@2@!E_J%F*rgl+wEXaJ15w}Zz~5OL^;b7?X^oXzItD4KRHnT4-56%obXsso$}Q!J>Tj#WdK@X4uqDKyLhe<#bEj?j zzUI$w?wR*fyLx8P;Aod4fS%7s^>Hmuv08UQ(XnLZw2eGjc`dR52tEuO>s0=j|95fA zBg&t?e_ka1oe_bfuZUyI%a_|paN-jH?@dKDu;A3GE}hLDm0P(}k+hiiZfpNPCSAX0 znwe0RWHRGcnB~LTxa1XKL*pw0R)>su88obAWsUawzsu9#zA_80{Aypdk>WJ%^`y%- zD**NeF|zp1v0y|EZ)7LP+v%zso7?MDF3byW#Fb!eLgp~v3>j=-m%y^C!97AXf8NP1 zVJ5j7OC|Dh&(WhD+y=D88@$_LJ$K?*ePX=RG>(Xn;bb+8a8nT#h;t1PW?NOi+!&@g zwQOM)A8rIX5IB2d(TK%fctkU2R??%z6g~qwnDCO2m@3sm% zEr4D4jD+2B%tn2p3tM=)h>MEbfO8fe7iaw63{(HOUFFFtlPAxvzA=5DACj`9|Dx~h zTh1&@4*haL`QM?j!Do|~oF6@sEiAN%f|bga8k!60(H>S`hMBFKRsGSlCjR}3-AjYM z4>j%1P&0!c>kQdN22^0N0w5+Ye$W=4^mrU>O4sNa_Sxe^^)LI{B=A9dk*&;JA4ZE? zO4mdh=Dz{te6LZ8x89J1=l@$j#%W7h}7|Y5Z7k7%(pPp~K$Lqfb`9E(v}3 zb#i1sy%`^@W?g@l$gByY6KFb?>eQvGW)BEUy_;1C?F&M+7m)Ztfo}8j86GQ=G{5$L3KDWqb5(pK)dOKBr zOW{+>R#w^A$V|=uw*kA`024%bUW8;wY&7{36u zNz^H)k$yohhFxIq*7dLo@P({S#VK#rtFQ@_v`H+f6%G*NmMx%zq}o1u))!X%7;j-| z*I&ot{^+oKq!O73$%LIwhsHPUvfE*YSvW4?7q~5@N5q>qqx%g|^d8o#-dJ#L-JwU= zeprnBR|;O}e7Zxsx#xfWW@cmTG-BFa{=?IflC3CLk5jKP8oUgeAv#t%GFhT1w(5k! zKk0ow&`#u4sFl+k$?OU%oxIEq>+lPjL!U29azmqaTbUbzr#dZKY_LK@S6?xvr=DoS+cQ7b!PURd(Kn)u{4QAb{*K7yo0a53YsKD1nc+%r7q(wgRN%& z16EaE0Wx*8*6y@ffYCSugHBzQev#Ffzqy%GNVneYwrf(KtG^YkVnkWU>v!7QlI{1&!}{2?z6gt9eEmhDz29ym&mo2p*D3EM*Blk$C&aCWo$0eBs6!z z%EV;mW$jc^N^ECJDYX|>DXXNHhOOK(O9tWvm_Wb#c5w>p4 zxG-axVy3TiMcC3gK^U8QQH9M=9Fs!(j>;*YIZDm~hKj8S?$VMBUHbShm9FX& zp#)>G%|FoAT+TG@ROFY$Nb3)wN9%Z)qVK1s0BiDww9!M>_yNF^Hae)@$QvW`LLsJ(%tjK&7a^O;8j{78Q8^l7DXAM55J@gf3fh zRu_3TK`T{-{!pY2p)CwzCE{}$@x}7`^vMkv4q8_uNGH)V&Ymb;V~Uk~Jz)~kY#itR zeqcK~ow2%mH;B)g^EIegDxGbJ|cc z%KVDvaU!f>rgOf&S+ZD@mZ)R(lqeT6hIm5&?fLm;(9pKzrHj=&)&57{)T-yiMIQ31 zixCTOFXOZNu~0lWX1McD zzk=qO3bL(>Yc16;*P-|8^yMaFh-2db9siLTXW5F<+dZXr!-Z1%a6Y8AUhs1X%}hgwZ>%1U z`;+K=GCuw@GThm`8S+*Bu_8QgACkjt_V0*RaN7$LoFh0JNgIB6;6l?y+>8Mbb}02; z^M1=VaS38bD9AiOLNUuKxBX(^=AD}HM_z@dEcg|UC^N|0QDz+gs2=y2d3*}r5EPh!u*CKY(y8@KK@?=YVwa<>6Lh8ZwBAp z#`5`#(o&7rFBk62jX2%t5SK%84D{*X0lRzL1;B2BqtE@+W!bG5tPWlG_M{gG(3 zsJvu4;|!!+-CYs#wKs_hzsC*~XxGHTIA(g^yrlNQb1rxIaBJryP~&#r|4+}!GhrX@%)JvkZL3*(WPGfdA2Pl z)FE^IPG(~z6ekLs;cQ;a_%X{@=4a@TWwkIc#eH-dGk^3N+y>svWx&7>#4f_9U|Qk5 zU+-dHrtAu2Dk$S#$q!4rH8Pz#l?&gbKHDLfjao^84d6ZB6zZPaU!v9m(G~ z=u0MsI@=7Gh^qs%cVlxE<2uT0Syx-?KARhBzur$Nkk9A^E8%KGb+$uGj6CDNRMM=5*! zFn(cU`&=1w5Q6ek?)m`D%HWkZdKerChQ-U1fFZ+@+l2!2AVvLn%)(5T4hXXjBvEh< z8OL0Itb8gEA(V_*g}28m*$T+_kDGt57hXEWwar&zvE+|n#WKdi5a7REwqkSe_gn4$ zGEKv48-3mYz3tB>6j8lI&$=)e-h%A%0r}!kZ(YR>IXTAsQ~?=y3;E7ytfYR!ig*{? z#4Asp9F1QaI-S`ZCAw@(_xPw$r@Z3t*@Sx>g^ewyBmXFC_raQgdKLT~LkQs>5;Mi( zHN37a4r;aTTcx_pXJH3nuJ`ot>Y^>^C-|b4Da!xyKx7}0NKJ$Y#uV*1g?+fQl`VBS z30|Zyc-qu$eP=`Yt$BN|a;sR;>D$3;6sKF^Hbehm%`Z1kZ@7pR(#6jW4AM}<7%g+l znR&jI>^xIA#`vXH^X*_=-5378c2~R-2Zs!(S&ITCkHLw83P*w^~ z(3T>7+yXOJh<89?mv9t>mKuyNK4(gT3^=GRwzVqS;zzD*MB=+^> ztuSsa93}jejQ}a`&(nyRJaJ-UYLt3Zt>RaC8eWoNN>~;-eez9M~l>=w&q8; zvr1W=}(nc>+Qi?Hi8n>k4N`e%Il&hD< zG&+}^eqXElpvAX`FaF~KG&(mYso1QM*fo#`Y~NZZXV2Ba{>u_%7pa}r0c8LoY3?rby|Lh{8kp|9Rvhkivjohfur^M*Y>M%RO5jY^;u#hzREk871;5V#S;8+q6u z&+v_8&oSGSZ2ua!lF;9q(v}n|!)rW^Iq!l6*KH5iH_=?I+#mNLw~*#>j#;B|mB=kw zRZp@W0Wd3X)N^KOzG+?M?{k5VWYT?OGL zXmuRo(nie96}KDcl|g}%#qmHgt$<;0(`00MaW4THv{8l3&%^RYIqm0G0D!0f0bQs# z+`#xf{|?)mgN{flC|Zc8vepuMqddUbmlTThmllKN%A8alJR=~XLQs1Zqe{jZlnvu8 z?AEURp4I#^q#@y6DU7Av^7ZZNo7x=M^N-8d;ScUPaNv95(vEbZL6QXkLx-S zo%uOGTp%TWS%SeeD3D^>2fSq4TsFE&?%?}K?hsgZd3LdmL&jJtcOt?HB0VRpBQJal zMkX_R4jVXZS<#>5^EPb!1-TWrojiE7mON@Ly>3dO&-jLh@&C48rt}t)jKXFjimXH8 zI5V#5r`d23(-uZ4YQsk z$>cG|Q%XEqtg7$dCBB9C?i5LhAlp7DZ{NO5>e@VgSqm1rl7K|Ch>)1pjX^II(J_47 z?Syw_5$K5}FU*}A=I;111Fx|e0`w9KQFGZ)(%Ra6?6vJ?+fBnFtkAu*nCkN?Nue*&I!OCqxTQ21TTr-rmb*rlwx_@~3-RT2#F6@}?kWE7L+* zQ628wEDW19;1sdF&Z@3dgs0w$x(#4PhNa+KS4p7qXsN?@2AD0B^|GSHgt6~$@R@m5c247LdA1X90=zJdEMF5^jA>ob@7B>BS!^HwHlym!{)Xj8YN0FZh{(~ zV9g0Q!g{6=s(U_Q)mxC9IMbc&L!Uh}`F2~CJ#9=n_zjLqTr(_?ZZDe+3ZCOqq|=ff zv+=(hoLBH02@e@iTEv}#>5va{@Z&}*x;tFE8gDz9X39Vk2LMVtY2FCiA3(wsk2JT) z7O`e=@$BDmojzte>SqRY-i=#!-VtDA(3UPoJ+;kS=u|$~B7#RU38_qc-*XJhkKV6t z(`hs8RjRQcJc2$rgR_lXCKteeFH}74#?Q2ITOZs;WxZUFAcs45y>t{r7sfC_xTa87 zcdUMWJ4<%6f`5r&Gue~J@jZ+SAjJqf!p75zihf82S2FO5=+w}ogOQr*TMw($_A2Y* z5p)7}TqR6U&iCVH5cYqkF7dl1{#-tmzAOXk6HiIdX#Mq7ZN&SVQVoUv7D%(H1x|^S zNq`bkNq`4+LYe4#4&hlI4h;BBwtm}vlbNPFrxEX_-+x?hIt z=I9~+J2yAv+yn=EG3^x|0<-Z~*EeZe3||JSPrCD3y*W7Yzkcidir(DN2I9rWV0F&0 zVRpO!e^FKz1TZgck;}~!V_vAm!Uyd*YHf03raLn~l9lMwF07oF%wvxByLY894b6=0eM99dUOG}7 zTtv{{m-~A69qLrHDkKl`uqw1JCUt9 zk)VFE4-!XRF&yZi>eCSTXB*WD5R{+xaHZD=U}p+{j!QdupW;gk0Z0hyqOp)YO`yhk zr=2En5I^Pf#>Ff_4kEO766UT_W6N>d3vZUl^x^4K^MVZ#bOtsJy44LBEWW2^5vf4=pnk9kJjlaxmVH~e3SKS_ueo+(FFQ?GHeLRjw}%^=dyVfs@) zzP|az{E4)GLM?VH-Ce2?{26@<^Wa_#NTF?tzpcbwr)+D83+9V#mZ^=B-H$9<*$Uf+ z=2B6NdP(nwIkCH`IpjPF%L=-eSixP?S#upPJ;t|`soR0`iV1pE&-YA~9bsbM$tbU_ zYLYQ-cYx+R?Tt?n*mAou$+G71^|CcKqz# zXuj=cwMQ$xt(B#>VkVQ6mM>d%uZvppp%pGEJ~S}Uo6ob7b_0Hp4!XtV->oktn7~#L zjidsl7AVgZmNc;7PdwVwOM0EV@vD|T&1?w{qc|tFSB-frTVQ1=9V2gvUMLOK^n$N} z+Q=wS&_jN(tez18hnQ{1IPb*dE_q63Oeq3kz)1BZ(o%G3X&&!cX8Co~JN50gRfhd+p?TvEoSV>#4WV_R+9j_(PfC_he#&ff=#v>IS;pBi z(D{`;2M!*rS++K5jgt*E?Ui=N7?}fir5DgP*SYMKUli z`%gAvGzYUM9oi=9=(h{?ZsZtygFSfQVXPEg&g~J1kRa1R)$daQ?b&uhQEx4+$!;Ml zQ=) zbr8G|S+n0P&x>UNp*xHZO98+gY=6!x8AJMCqX4Ctzwh5aAAOex`cP=g z1K#$!XmR{kK#`9*8IyA9Vws5wmqxsgBsBqLzyr+JQ(15IH@#aPS`!&{xwY?=-|H9A zmRV9y;01e+W5}*Xju86fkJ=0p zhb$|LtG>v1xB;|2a@umUs-~9w5X_> zmw*9Nr8ef`0TGwr0@{||R{kXK_}}9*Flg(+%4cbQx%DclhRehR94wLJJRVj)V~hrv z6kxIzzH**N@L07*Qr2*qk~kPhu%1zv2oDSzqRbuL$_h-}4C49C_6?rbd}GzqCNd}D zp;4{KpP;=-#Ue?QKc9q+-Fev3T`2!%%6S;aK^_i+L!70gex)6i`48Qpre5cuace7{ zH47)R{5oZ}9(UA<>qMLq46gzEH&EJSPf~|+e@F`{BBYz8=B!7$*euaMdEs7Wt zTtV|#XFYRt^kHvD1Iwk-l#^Pegs-c*y7t-{gq$3FOQ_Ydyc^LA>&2$ZkE2c)SI0|k z--k%aVG}PqF~@Dud5E!_n!LnbZMXgJF-H!=uRt~mh^@=u{k!;q#LHr?BXkZOSw_!T zP&P7BWL$-r?gaIQ!KIO#!BZ&{nC}BLi=dE#AGyb`li%i7gDan{yuD5};*Lvz%QLDB z4HmBEd=8G47F4z_H-;QSAq5iE7D0jm*3zKrT6%5kPK$}c|NZcC`Qg;Bph7|1 zv`8bIqS<8I0w|Z8_3Z4e(OYT1#XazfaxVq;W0ADmNHYW%h#_zCqI<14Q`Z>e=3Q8| zpzZ}vx-L^nP#1AIC2O$l0q$Des|#-Wzr(_BVzrr$lFCeWJ@f5oF}st)fa+69T@38L z^3cN*nzZI`9XC#$^8o8jK5A+bz7OPa$V}WzuzCQ>Hj|9U&TL}*wLsP zas&*G=q!nV(r+T650BX07S5a>BL1Gtys5gwOWL?*OD7I^FSigLvy2#kT?b-{!BFF@ z_hjW4WH|`65|S83zsXW!@mVnLn66Zxb+zG|p?5CCf4i%Tsc<0QE&Ex%}NjT@l)e$l<>uG|tMf38}B{ zPunF7+XU+co)eAOdWHamwZ@8BJB*zvSiEVDb_R@#Oon+~!h<#ZSGR}|OD*I@0S`;) zLv{zpV=~roE=#8O=DIbdx)E$)bWN4>e;+XX{*^kUi#*6gyPDnz5W?-m{5x`B0v_P04@PFu0AND2-oSxC(sTX<`gL2Iy%M& z4=mu`<*Yd3cuo25=nVY7qZ2B=R{*W2W}I!z4C7DA5A$=HT}=B9vi%UXNj@$u9%$M# z+EyU~G3ObCTW&{8PXmk^Ypbg_5@&44-c*SS3NkO`>N+i0;6vT7I3;?Mn4kc^Qddb) z3TpCSnEmtr!mRNYmTAn&T;HjV(Bs{L3;pR4eXUsk0IGE2$^3~uiNKk4IQWpkZOEvG z_PP`4WB?TD7Ddx5_Z9}6fC@bNc+RrSRjWwKb)SF9BkSLvKfhjvZfIS^B`$5@tem;; zw?n)c97^xTb?BzQMk+xJ`ou>9!V<*uZX!kCdyD5b`bI8o12KC8_fqxP?#YVt!b za*sciKk1HUUGf5*jr#9E@w#bB9Xu=t+Oi&G#J67lLr9#R_A=<`MIQ+?psecsX%g<% z=KURnz`~6tlli7CTnrvix}&jFNFsS=?jWoY_?J5Z)CJfb>poU-kEb?%7bw0z4M%hY96cqY+~;o zx!OVN7W($tp6f9@Ys|}>3zw#i+ww}G{GR(^#o>=ujk)AB@%)eVg9p3)>weD_nVwzd z`U{kS1rV?!oQE32w6Q@8hvV-###{fc|9EqvQGEq))trG(75QHUgd;r#v@-G`x`%N6FXn*>7u36)Pa6(T4_ifP9!}%C*pEm*`RHhSN@5%Gt$#q{t&$L5SnIMcEqYUJ zO^TI2acrW|pS7!Dq(Zc5#Z}WJ<)Cr?*o(5ztXWdy1W+&OU@6cgEe@{@YI1W{3b`Y@Y zAO_Fmb4&kySi0~0UxZrau3b-2c>$i90@dm2wdE&n*4uTZL*36FtDBCs5LN97pKfc7 zp-N25sW&a~C;TM4Gjn%hL2(Le4lA5mPOUxV17vZIvf)weH6}Xl?;hSwiCuANbG=gw zlbwMWY?d!S4f!XY$y6@Zu%*WG1ImUscdYwC@_I3zapgpIW{I5Powe{+4FN6qCx_u9 z^fUpkIl9EEglDjD`FP7~j36Uf#(9p*j91%j_j~pWe!Z~I3cp{NLIc|YD*JEFk8oB{ zcx&L`aD-a8y^_*#%7`*RriI)k2s{Zqj+Wi@_nn!hx@Z6X7`~-D><0=9f_v!iSJCdj zSJ9$wkTPbIgHFZ=FIF$OV!P9FtexEfvhoT3>HbN5B1*|^8UxFEmWDm897g|kUq(#4;EmtY0d5yzY~ zo}aM@VVT~>>hqk?7>sPpNzNe`%c6lQ8#QSXM^b6ty7kGojrh^W9uE3_*Dj6aC9Gvn zAZO_$ii_9Y9UN{GWBmgfjXVR@Y4W~-PCQ zxFxTB!@uC0-=i9nOKpFC`8Wo)T=6^feeREzq$WK}?Pg+XnvaJOe6R@KQ7nVo-xt5N zd6fhJ1%=ZMDE0G^*(i7E5+~zqCMg5;+P-b*ty8cKHtp*@Q%C2~T)D&3BHT^l`2_p< z`Q_!6W#Avk`JPN%{0{07!DL8xSOzmR#`<4xwdDDUv@Yd(*^yX@C5t=rZ4zOS;6PEF)-Lhhj5Il z${vke+M9%Q_O+a#u(|=P#7`SHrlu-FVjnIV@eUUcR7%X*+}ZH=!&f-%%+dSdTz8XC z(vtS?)oVPxk2OJsnNp-u?}@M#oys0xIGZ=f+zb_00_u_JFgppRaT;IccaB~WFtLd| zJWkf#|J?|eu^Yd==x`2mA4Vni9V?(n+3@AT0z%4Qy;hqWKf`!GfPQmR~U>bG?0R z-1nR@HOINL3qf+>2o2M-KF4(RJaffZSh~@4+hzZzr^2i3#dZCOXiWWn9^ohH>P*<;E-6L0seaX>BWp+f=o9A5bOhlIT z1EaybCmK!A1&=>iw5fK(hL1OgO*E<(a`0dr8plas5f)JUDRCoD9$9M&a5d2= zT@%zFYsl&RY%0`bI%#It#;YH%@L|>ODR?-!IXO9{`%eEs=W~xz)vf&E*D`z^=iMC4 zZ?oCX==Zrg*6Ih0n@?PX=~OR4cF8Wsxe(_TKgch&RVcf_wn<5u9Df_+k)IMb{k&0X z9O{9X9j>YdN03U7c4SX_dOBy9-fbY=aE#p7oNb4{lc|Ofwk97MZjQHj&v|v}bNeyI z1@dQFYe*F1i77z2!FlEiLk2<#SjkX8@0$8yA}e4&2*UZHOK?QsjxH*kM2sX*Oy`>F zt$x4QZBju!Jk1Y7w@ze<(lk`9dy&Hb%3F*R`d{a1VEg~le&g`-=WS_hCgv#I-VC=WhEnptKqs$m z8>^h`QPAqHJVc2x^Riq`sA)lQaf>eWbD(~Y3v!OA`9UDS1ySwiyJeg1P_6vBGn=3O z7f*&LfZLYkMffbu`swlWN$t<0Ts!}OhR5om^$L+a>>JQS&@SJGB*YZUHBZ=y z!UuRzIE0RKCViI$hKahsC|r~4IXNfy-co3pO*;5|FRR8%=i;YehqbTOBTD3Fj~($} zyy)D6?_OK|YRp#AW`M(mY zK?hY;Eohb`t;?kv(U)-J9Rl~RVv&A<5k$9x$QG9@>I_{kk%3u%OiJVd51zYY>4g_6 z5zgWD#2r}|4I8-Q)LZ%=cjc{+4|r_+|HA&}B;LiY0EJ^)SQ%~&t3(P&$}mkraB%yM z9iwsRa3rQ%Gs=U;8x6r^119$e^gYjzuNN#|Iiw*&hPyO|pEw_{`7FbJy}(&*|0}g- z6*9e>H}v3L41OXa6r#7%nj}*T0`i$q)_y0H5c*F5rns=80e3uefXLbp=Xr!uy)MhB z*v=!46Vp1dm&S+cb@qY^`iB0w0E|`_N3~zC?b5sv9aZJy@#o7sxPj(q!#NuV}VjVd8do8v;jW3eGWSTnBd-xqv6o)uia?|0IfZ0Ert=0Gxew{Sy8F^m)zKfT#& zCgi#;^mHkOw-4rXccvI}A@R}2$N8_he{hW+2R&g>n#0UhhYXLQ=9B@uh3GJtmpTcf z$>Fm@B|#qcYTfjQ=U}WgqS?j&$=Qy2hKAP`?J$d$9Ak28%tfZEp?Maeo2n98RrGxy@k}nI})u#pd6X66|t7LeE7> zk&99NCAf|(HHQmHRi0|z0Pks0Fr?9Kk;Jn!mpqK$N(q$5Rn07bRhqhzi8sa_X-PmE zIUOfBCMi82UM|?B+yG@dX&`$vDvLfWgNS>7! z<1wnAcKQSkB9=0N78*D2o}Ub(VqsqP%Zbab0T6i-rEFMrq}`N%WRo<7ZdU@;$Bol?S`?C0g{n|Q%n-t)@(wv{&pb28GRPl@M=ifCftGQcYs zzi%2Dlos&o7S60YuT`sNpWe`jWAroloM|lWU{3Kao*l1-woZrf_Ge>B1eOB4%z6E# zs<}RPvuE#OIJ4G(0ZFKr2+tgBW68nQii)gsEVe#4|EVrx89x8)#S44J5CQLrd~@Rm z{RRxHzVq(wnk`pz44>}^cry`HsxXKY*uT-e6)sYP7gxKX2gQXc%qAYI+^{vkVe9)?w#H>_7?R@TiA z7DNq7rrFMB{c~^T9+@?o$oPA!Yq>@=B3}4SFmy4xYmlocscVH_c5zl zeB(Ye)e9aqhEM}ZUaWHS&GQ%)k9#HX#d?m5GIGC`;4p1-)^Cb*z0sp@WE@?^Q!ov9 zdrHbW{k2;*Z?2-I8EL9G=tFzB*^@Kv_~bU%6X&vi@&N3WrsMWYNUPt%8P_<4$piu%O@VG z$-1yQt_UWuCu@!vQC`j(hV##-$$-nx@Y#0z_H8e3?}X=Fh=&IDUrwJfBdzfbX1fs8 z8+o~qld(vXO26B1o|Ijx`RlHEj4E815d|A7{yNvCOXI=jeNkgP1H&+YB&p(U z=FcC7R90VAJdp-+E9f>lavu5u`#66DIGxY=qTd}u zZHfSH%WtQ!%6anJhkZwT=_GZNHR{v96-=B7dc*hu1#WI?9sN@k9;4hbXajVUDi?n_ z0d|8rce(yrg3NSQ1jgTtAMME)^L98`3XV*2R>9KgF#?&(6d*Tv=7AUliu#A;Wxg(S z@6VPSrLiZa_`IF1En{^DTzMO3%6KK}T#v13o0rd)o4T2Xmf_w&!k zGY4bm4UgRvvJby!e@a~E@tu2qT}Tlyvb~kn&Q-c{CmQNj`b^`&Oh3OY9xc@J67QZ9 z<=i#kqSo$Qiw_5rb56I*x4H_?OFg_;f35Hn!22vF9eQ?1!mnkKlyOd7ethW;EGvh# z^zAP4RwS*^I%aEQWAkVOw~u~Ywyn=dh1nvQLC=Nu)sqsa)~5x7eF~J>a-nFG4n=dV zKkEPO+~o`B5pVFZEOM-<0*_JlRLu%#2to0mcc&9qe%QG!M`e#hz7-6C(VoZE?`)?{`z74}`8*iF>s4;)cbRoZ;8C-F3Y;DTg=y(@6kISq-%6VY z7(*4}m|x49P~1q3dUW#MM^LwVMn*P>B}plFKaP7Oh?N-@>u&rOM$(cR(ZKoC%Y9oX z@nUcCCO!SXqgq1?aZQ<9ir=C9d}4{0J%K5ydTqV(!op&}h3BDj^f*4Gq~V(g;(K8l zW61@Mo&Tt)I9MiWexvCRt>Ec_1Hg}H9{~mse(W8IFBK1j5;g}@{fH4-Cr6L;| z%3|4q5jJXaQBQ4c71)j}S&i{YC?z##1`_~>P-C#GX7o$71{Y*;9IrAYWc7vD`z|dJ z_6N61=+>>%qry+aY=VF)3!L~jY|k9%HjgclCDS1d66-_zrhy&G?`NmIzdJa1;p^{T z)TpORWE`P=Xa%>R@%)$8Td3Jg0A)2yaY1~Rh%!b9XA42#(Q%afyK#0yraK3txi9ngQjM| zojWe*_FtMdF)5lsZP(s&>jf{{ke%X9r-e`ujq%R720kPmxprB2rV@y{Df;6M0|l zK0Nes?I*M%fvyv1`0=3)BIj9wz8?i2NqguHv*&w+se<{l2o}N|tiMtZ?$@0UXJ~Dw z?*eofMwDbji*^8v{NS_t^Q2F~Ffunr%b9+UBcud+m8LSWorb9mnR(xk8q3SGZ|##l zU}A3m;gP?oc|7UL(-!s<`hUH0T*_-<~ut9ur_n$6P3W4k=o`-*EHIMd=R80|z`D zi)p5c7e1DD@idiN7fMmU{`R0i2QRwT9REC)_D0&>&<)7RmYmPQiJDeO7i4^yvD8Pq zk1?~P@}8SnHJFKS5Xv7t>3V?+OS|UA@nc9&3h%|TzW)^>O8cRIl)(cE6jU(D$?xyI zONAyC#MFS8;#pfplAxzD7691iz{_Xk1aI(H4cXj}>6i6XxWwMG7%-Ap_ANUX&HN%t z%BUQDB9O>Qd6Nw2OrFi+Ro(JgbtLc3ojV!(c1`G}Q%x^Tz{_x+`YuvfSeSk0H*yrjh?b@{dy@Ze8V!u*?5SK9uNJsBCtVGlxeTIbp)F(apq!KSy*TH z`uWubxh1JHC+okqIA)xZ+Rav4a~xmk!%pC_DnVky0;j`-XvcQLKKpE3GpsUd+J_q7 zOle)s^>f%s0Nw~Vgepw^8P(3NlIS^(8G3Wq=NhbG0yh zlh9sF%DLD%TkMs1r3k^9HrETqAp1{lfca;YZs@NE@ z7$7k;%^{((RR%6ydcW_qZV_xliKu})cG$BjIjkTwJlt^Wg)cbY(lIu=uH?wXju8VR z+Ofc}Jr8@~p9Q5|dH;SqwV~8Os`vkX{CGG(HQG$-v97J8tVXG0(y3>GB5P5O7Tzv8 zdv-izWEliQ(z+iDfWDqli97_y@wGTugCo&)W^>=e?f-z#oWp#W#D+cKxn%9*X*M|D zq9q;#lVpy0O-_~YR9HA2HZd!DwW=%cxtQWDf$UnKNU!<5--=RN9TQ)kMB_x=(=#=7 z5Xu^uC*?S!9URZb^C+lvRv8@Vps-%GDuu$-v-TgF$p}CRkQBnRk4lM8GrEeqCt_gx zFtFU>*BcBQ!)fBT1tNZ*oMzDJrTd{{-S%$ z7Ft~%5;x~}9!6HCE(Qe~n5Ycd=?r%C_|Jmkbenb(1JLalky$ZE-{fX7QEejX_ zdZlN&3(pUaT0GtTQZ*0u70QHx1o$J5U~wVmo8THUT1`p*rzu zJ?bau5B;ydo(l#~=v_PP=~x~kUZmBTUS#ZS90a;}=%sG3TiLlw7m>xBLVN#kb0^jU z7HGM1KX3`qmYilwTJr31#^S@BNNqXAy9CM3Z{J4lgrSLO_3xjEcea*rXZroiWEv^r z_`Oxw_8agh6ja(iZnl}b9`DC9|;MZm+*^qf*lh&k}Zc# zpEc`*vfQFfmnjITw{*Uwefd>GgPr@bGm3PEdrg+aMeR6$d7S-Ff+nY4%mcfITv&(+ zG>iiuIC1yrH;+zk>ORrTi?}#w@ZjD0YY&cI&4D~KN!5n-k0fC?X=UxQgOR!bei!oc z%CGGg1Q5(Ii*|_`?D<*advUul6Wf@hv!hweOd3>S`WIwOTqB(B4DLFqB3`Q-&{6QGl~3-re?F5vAo-vVFx)7WB~A z&QGdjHiCp!cM zuQMCJ;U`Jd2qT8UR0_E*RrTuC`X-$dP)DED)x9~_Ga5j2>CjjgC?Ara`4;OOJ;5-t zM+eXBYW#p7URf|$uHEaeU$`*ji9*XyiL3U?!c7R1fP#$fbC*?*__wItEIK5JltDd>dVU%73e)H_3-Z3&JA)HuwqOglZ@=`18gICxa);kb3h8*$F^3*(IA@Uw>(l4J zCmVH`f_o-IGqui>@|FnuS8c81@|tjxGCacepe|gY(U3O$vJ{}IPfE2LqUSX7Bo-~m zGEqn+m9zRzEJ+5IPMNym3hO2vQ!vm4JaFTAdim*q(}r*BBOw3)NK|eR2?Un`;YEu_ zR0|p>v$$7xvFd|C(SFXHU^1CUhh1Q7;jBOv)Id~Bf;WqIJ=~YSI5o$m$LZfq_RcVV zc4~_DvD60!vz)#Ifhv`*`YV6W%hMk^)LcR}MHlIA>3YwO@4tWX>Q!qInjl0|&5R3NBu>B5{FJ zDjz>yp}&UuCk|$A%G5+_L&HI~Ys_QQX4qW~=pUoHXR|w}GPah-h5OLs>g)f*W!h&R z>cCY_nc8$$U0d(!OB*%~WIck5!m<4xaxl7}Mey?6S4+y%5=-)(cx6Q5uf86wC?GEv z`2QV$UPGf-C-X_;Z7eBhh!lMK?(gk`mUJe!mp(2W9)$hQm?>OWuIp?h?B2Z0^ zvCK%bg4!N6YJu5GgAPdrV|I6TiRn!7D@c%%T-8Oehk41s9p4^hy7DInK9+qupl$Kn z$(*x*Ay25T1YQP50_B}44>I1HRUHMdtf~8Rj`ZHBdd_wDcm^*3o{D%O8bx{EqLLrw zn47%~cI^csG%2n>#_4Mb3m*E~4r#m3ajpP|zvU{Xw@Hf`Z%di%*dO^1DtaM}~d<(#3T{Iq< zcClxi`w6&Avxce&x`9KflP{O%D7;p!yR1mRX<^YjN#|5)p6h`1nfGk!4ro=z6nOT& zALnM~I(bLVobc%f&qY0Rs>w9WRe4-4JlG@7kerS8`xyALC&`Eu*X&`6F=>5p|BWLz zilAdLbEcpq)h#wb6wH8drL1_e9-Jg6Pe>G@)72!p-I3pcjYG`La_0Ysb}CD})}cC3 zOmDiyPw;1*!b{#!in zBhYMxfK0k@q$VKQ0h6&^8F0caH_}I2dx)-yNm+)2(V#&Wo;Mx{2^nY(f$5oPzJM8w ze9LUgsID`YpN3U1UUT35x&d4f_cO)5Y|;6l~=)(*csefI2V zmrbUR0S^Wzel()$p-CoGM;L!(Ax+)16(R)D)XX5+G5)A>;;$>-Rg+dT?0YB0rF-e2 zzZ<5fro>H7C_K2@mM8eNGIM*Xef?UjV09(ahgXZGfHHAUm3Y=lKW^RFCy$DhC`IB= zA8E&-!Id}O%r1EI!;Px3Ph1|R)c%usBZPt0+XswwhHvqqGk<8R<&jYke>=p%AE?RBJAF9kI=D_P18=-u<*|(4?9E0_8=6~N7()cC_bOT+wQ%laE>?N@p;umP;n?hL9If^_ma}8VxXYRuJ7q<%YTI$;B3y~9<#pv9AxWXueNV;n(Z>Iom2U9L-OD9_r1bngy2QVH(Z$oCaoia6Ru&eIr(454h<%Z!|*2VwKU+#ZHxjf!Y z`{sqm_FHno_vc(JYNErvVW=7KGaHI8@`0@-XeJ7(Q-CA0{;p8K5m?`}b4`jr?)%UI z^OC4GY}bh9cQ&H+ot@Mp4N<(7F>k8L)3kTQWDo#;F{Sct%4u)2xz#?s@Ay8=bA22T zRc`2WAaJ>U{DVAu>uJgNS0C?4@gvluaFO&>%wbmluaH*@y%YQfk&U3zP~XLLAjg=ypgOZ{c%|6Ayp>8&q ztT-hu^61#-Va{t}ZGY9WjMrO#XSy=naLpeDx9n`|U)@SngJZz2L#P6TG8Z17m!*O> zbVq@L>bio(2glTRcxmmAfaI{@r7ihm&k=hU|E6*f2(~RqoLolJ+M>@TCZb0W$K$!u znybfnaa98&2CDa@h9nvqeyQ9Y73bigcW|3)UBS7A@0UkWw#JL_aOCIyB|y}4Ce{&^ zE>z8}cjg+TrWuRsEndl*`l3#U#|VER<`BFL+FsaHd;HQ#l$o&eU-O&DX1V3 zH-~iD3mYioeIVlZOxLp2bNF@c^Q@8=!#B9ks=1m;9Lo9U@;4H7p`B!0K!LL+z}Syj z(DjJR)y%e1v+P0-9a`a?(0A3-+N06B73#XL6t(Fd-NueAh?~)Wec}9rlyz#%qi}(g zGC`?g+g_mCntTu66n%o&kNH$~qR0g3tqw)AGv2IR^`Et#dg zj^VGbmy{Qd$vt{MVaN*q(I;+t!3#;P`|d@+yJJjAn}^$4CY&hDIu`7QiN#Z&&g?x= z>PduCrpDRzK5bW!XrcPm%gS=Vrqr@Zb!nN}jW;8=Du@loR=#*Bn+)J@$A+kH|9!5> zmZov|cCv%2$u@Iqb&*)8m~V2-W0OMeb}(puni2JI)>F;Ob`S_MVLdOL$Rqk&@RPUVeCFRey;xU z)OtnG?7gcKs&ZZJf3vI1(AR!9XNT(11KUfpXD4Rm-b^8Xb~CHn>Ac~Ut9a^G`oBUvGoZ^sYI}f1DI0lv z&}IuMFT_|toi~rx(nEy(ZzBfUZY_BhrdAl(Yw8)mHm-S^r)8G$fXL~5Fz@7n!0>x_ zYvaAjE5rZs+M%lYG-=RlrPnmAfZW1dRV_8I56_|o>!ezAJ8^oEy6kcOBO=ZKfx#I&MO!1 znGq++Hd1p;nX0fV=#>zc8lL<>Cvj_`wX5znTXkjliL6xnL4_B3oUO@%M5*vC_kJs9ls?gz1L zv%dV4{p#=ikk%1P!`Ds0_HYGqIcO zrhHSwZQ_gWt6iOHXum)&dr5NYis^TT8|XSEeroHK7jsb=9#MB{czV{;yS0V=vmY#) zzGC?6jHCB+=6sd#g_ibxi~GJ(RlSP)(7it+n2hjjN|TT<*<)V))nmg?!g2fT%vU^q z*U-EL$8BO+N1)ZB1h`)a)N01)3pyeuynR&^P$RYjv?=M&q1fj>(j#GW1v$y$A{~pZ z-q^Hcka|l=x5P_PxxYVun|_*nDwYVag?Pi&XiON6`Gx=0Yi;__@Ert)38y5L3vbvt zpwS1W0}s7s0|TmgH_?D^XG(TEh8MdgY5tBgfoV$W7GUaz5aa8Z5IbD|omEPf!*e0e zL>u8|NRC!bJry-y4{qtHIAcgM6e0`XdxC_w;khp-G?Bl(6gQ~m>v4~WTfQmwGkpjj z+yWNNRd`Mx!Fh-iLKT?K+43MqV{_cl?A+9&z*!p~A0LrKu}Vc%^Dj zi&;n`doiMxxTQ$;!k}VjIl@SDV#IEdJh=C>Wo+poGX5@VVDs;**#CqO5t%Z0O&jBlE z%GB{)_nP{|wOBeo(eB`L20_ed!<)69*OSN7&6(NcQW)6or=fa!O+b*@ojDA%l;*vb z#w(4sAH7;!GW+*S*OLY&!=`fLlbA&i9pT?UGnXtT7Uhve-!AgjIeZPTv4R6bh=y0W zZWXE+L5FJ{*L9VVY4c;zu(E}06MtawR~pwl<023b=!siiTSbP2(p!e-eZ+ox58Ep) z&{<(b)egvVW5Ntx6qDwDgTCimp#w7lQ~c@`Qo#28dgbA!lE?kpACx@XCDT93sx{=P z`ZSe0a9qv#BIdh~T3d6l-eleKe^C+m>#v+?nr(#L6T!4pzJDI!40FH`xOlXY?M)Ex z%D7fb3#dh(Zdvidz+IQJJs@B|(e51MO9x2_^}WLz@La!|E|}U6--? zk$>zlU5X)s zmJp1G$G&@2Bt2nc5J1H2)m+9b(3l$0jQ4mGR@T@v5yVE&1-}ffmVVVk5^bcDE~1@n z6Z%Bkf%CTIm+%-`+A=lUd`cQIqMbXhtJIPoLA`zxE>}8vnkek9F`?A|73=OF#4~g= z*FPHqzd72S8JFNKQBVFDbqaV@=#oZ{_m-c3cE|rG{ZGZaHtIKd{hmM6N3R6u&29=@ zZTUpw%1YUl5<4LNmS;a4B~&XnX;@81kTmAOV?|PT(xiB;8SXyVn6F58*#1#V)q-(R z`tdNj9KnB&L}gA1Mnjv`Wx`-RvSSt5xzuq*&Y+GRIaxq1_1(l)#arXbXVM1S?b|0C zrHT>SQ@i7kV}LsbuolZs$BECMtggoaOB z0BiY5%)nN3(ej0H+T+_Ut@%qeom%&A%SWuH{=00OzO>Qw$5www%SZlyF6I2Y_6EuK VYMv!tT_fLRK6&P(#0d+2{C^Dw;lcm_ diff --git a/docs/source/user_api/toolchain.rst b/docs/source/user_api/toolchain.rst index 5bdc1114..debbe45d 100644 --- a/docs/source/user_api/toolchain.rst +++ b/docs/source/user_api/toolchain.rst @@ -64,7 +64,7 @@ Example for Custom Toolchain // Selects the first found toolchain // Runs a verification function on the selected toolchain depending on the `ToolchainId` Toolchain::AddVerificationFunc(ToolchainId::Custom, - [](const ToolchainExecutables & executables) -> std::optional { + [](const ToolchainExecutables & executables) -> buildcc::env::optional { // Use executables to get compiler_version and target_arch if (success) { ToolchainCompilerInfo info; diff --git a/example/gcc/AfterInstall/CMakeLists.txt b/example/gcc/AfterInstall/CMakeLists.txt index 9445c04c..5931a007 100644 --- a/example/gcc/AfterInstall/CMakeLists.txt +++ b/example/gcc/AfterInstall/CMakeLists.txt @@ -14,6 +14,7 @@ find_package(fmt_package NAMES "fmt" REQUIRED) find_package(spdlog_package NAMES "spdlog" REQUIRED) find_package(flatbuffers_package NAMES "Flatbuffers" "flatbuffers" REQUIRED) find_package(taskflow_package NAMES "Taskflow" "taskflow" REQUIRED) +find_package(tl_optional_package NAMES "tl-optional" REQUIRED) find_package(CLI11_package NAMES "CLI11" REQUIRED) find_package(tiny_process_library_package NAMES "tiny-process-library" REQUIRED) @@ -22,6 +23,7 @@ find_package(buildcc_package NAMES "buildcc" REQUIRED) message("Find package: ${fmt_package_DIR}") message("Find package: ${spdlog_package_DIR}") message("Find package: ${flatbuffers_package_DIR}") +message("Find package: ${tl_optional_package_DIR}") message("Find package: ${taskflow_package_DIR}") message("Find package: ${CLI11_package_DIR}") message("Find package: ${tiny_process_library_package_DIR}") # diff --git a/third_party/tl_optional b/third_party/tl_optional new file mode 160000 index 00000000..c28fcf74 --- /dev/null +++ b/third_party/tl_optional @@ -0,0 +1 @@ +Subproject commit c28fcf74d207fc667c4ed3dbae4c251ea551c8c1 From c2e26150fd2ea7e794dffbaade79552d387edab4 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 2 Nov 2022 02:17:43 -0700 Subject: [PATCH 28/35] [Serialization] JSON Serialization (#223) --- .gitmodules | 3 + CMakeLists.txt | 2 + README.md | 2 + bootstrap/CMakeLists.txt | 1 + bootstrap/include/bootstrap/build_buildcc.h | 8 +- .../include/bootstrap/build_nlohmann_json.h | 28 ++++++ bootstrap/src/build_buildcc.cpp | 24 ++++-- bootstrap/src/build_nlohmann_json.cpp | 34 ++++++++ buildcc/CMakeLists.txt | 1 + .../target/include/target/custom_generator.h | 4 +- .../src/custom_generator/custom_generator.cpp | 8 +- .../test/target/test_custom_generator.cpp | 80 +++++++++--------- buildcc/schema/cmake/schema.cmake | 2 + buildcc/schema/cmake/schema_generate.cmake | 2 - buildcc/schema/custom_generator.fbs | 33 -------- .../schema/custom_generator_serialization.h | 63 ++++++++++++-- .../interface/serialization_interface.h | 4 +- buildcc/schema/include/schema/path.h | 29 ++++++- .../src/custom_generator_serialization.cpp | 66 ++++----------- buildcc/schema/test/.gitignore | 1 + .../test_custom_generator_serialization.cpp | 46 ++-------- buildexe/CMakeLists.txt | 1 + cmake/target/json.cmake | 3 + .../buildcc_interface_lib.PNG | Bin 156596 -> 171128 bytes .../buildcc_single_lib.PNG | Bin 128739 -> 146121 bytes example/gcc/AfterInstall/CMakeLists.txt | 2 + third_party/json | 1 + 27 files changed, 252 insertions(+), 196 deletions(-) create mode 100644 bootstrap/include/bootstrap/build_nlohmann_json.h create mode 100644 bootstrap/src/build_nlohmann_json.cpp delete mode 100644 buildcc/schema/custom_generator.fbs create mode 100644 cmake/target/json.cmake create mode 160000 third_party/json diff --git a/.gitmodules b/.gitmodules index 6c29f7ec..081a123b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "optional"] path = third_party/tl_optional url = https://github.com/TartanLlama/optional.git +[submodule "json"] + path = third_party/json + url = https://github.com/nlohmann/json.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 76d263e8..ec6ce113 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,8 @@ include(cmake/tool/doxygen.cmake) # Libraries include(cmake/target/flatbuffers.cmake) +include(cmake/target/json.cmake) + include(cmake/target/fmt.cmake) include(cmake/target/spdlog.cmake) include(cmake/target/cli11.cmake) diff --git a/README.md b/README.md index 8feeb09b..725ca12c 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Build C, C++ and ASM files in C++ - `C++11 thread` library support - Third Party Libraries (See License below) - Flatbuffers v2.0.0 + - Nlohmann::Json v3.11.2 - Taskflow v3.1.0 - CLI11 v2.1.0 - Tiny Process Library v2.0.4 @@ -176,6 +177,7 @@ _BuildCC_ is licensed under the Apache License, Version 2.0. See [LICENSE](LICEN - [Tiny Process Library](https://gitlab.com/eidheim/tiny-process-library) (Process handling) [MIT License] - [Taskflow](https://github.com/taskflow/taskflow) (Parallel Programming) [MIT License] [Header Only] - See also [3rd-Party](https://github.com/taskflow/taskflow/tree/master/3rd-party) used by Taskflow +- [Nlohmann::Json](https://github.com/nlohmann/json) (JSON Serialization) [MIT License] [Header Only] - [Flatbuffers](https://github.com/google/flatbuffers) (Serialization) [Apache-2.0 License] - [CLI11](https://github.com/CLIUtils/CLI11) (Argument Parsing) [BSD-3-Clause License] [Header Only] - [CppUTest](https://github.com/cpputest/cpputest) (Unit Testing/Mocking) [BSD-3-Clause License] diff --git a/bootstrap/CMakeLists.txt b/bootstrap/CMakeLists.txt index f07f53d9..3c50e1b8 100644 --- a/bootstrap/CMakeLists.txt +++ b/bootstrap/CMakeLists.txt @@ -3,6 +3,7 @@ add_executable(buildcc_lib_bootstrap ) target_sources(buildcc_lib_bootstrap PRIVATE src/build_flatbuffers.cpp + src/build_nlohmann_json.cpp src/build_cli11.cpp src/build_fmtlib.cpp src/build_spdlog.cpp diff --git a/bootstrap/include/bootstrap/build_buildcc.h b/bootstrap/include/bootstrap/build_buildcc.h index a4026f7a..e8fb8110 100644 --- a/bootstrap/include/bootstrap/build_buildcc.h +++ b/bootstrap/include/bootstrap/build_buildcc.h @@ -22,6 +22,7 @@ #include "build_cli11.h" #include "build_flatbuffers.h" #include "build_fmtlib.h" +#include "build_nlohmann_json.h" #include "build_spdlog.h" #include "build_taskflow.h" #include "build_tl_optional.h" @@ -32,7 +33,8 @@ namespace buildcc { void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe); void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, - const TargetInfo &flatbuffers_ho, const TargetInfo &fmt_ho, + const TargetInfo &flatbuffers_ho, + const TargetInfo &nlohmann_json_ho, const TargetInfo &fmt_ho, const TargetInfo &spdlog_ho, const TargetInfo &cli11_ho, const TargetInfo &taskflow_ho, const TargetInfo &tl_optional_ho, const BaseTarget &tpl); @@ -45,6 +47,7 @@ class BuildBuildCC { public: // TargetInfo / Header Only static constexpr const char *const kFlatbuffersHoName = "flatbuffers_ho"; + static constexpr const char *const kNlohmannJsonHoName = "nlohmann_json_ho"; static constexpr const char *const kCli11HoName = "cli11_ho"; static constexpr const char *const kFmtHoName = "fmtlib_ho"; static constexpr const char *const kSpdlogHoName = "spdlog_ho"; @@ -89,6 +92,9 @@ class BuildBuildCC { TargetInfo &GetFlatbuffersHo() { return storage_.Ref(kFlatbuffersHoName); } + TargetInfo &GetNlohmannJsonHo() { + return storage_.Ref(kNlohmannJsonHoName); + } TargetInfo &GetCli11Ho() { return storage_.Ref(kCli11HoName); } TargetInfo &GetFmtHo() { return storage_.Ref(kFmtHoName); } TargetInfo &GetSpdlogHo() { return storage_.Ref(kSpdlogHoName); } diff --git a/bootstrap/include/bootstrap/build_nlohmann_json.h b/bootstrap/include/bootstrap/build_nlohmann_json.h new file mode 100644 index 00000000..135275f0 --- /dev/null +++ b/bootstrap/include/bootstrap/build_nlohmann_json.h @@ -0,0 +1,28 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BOOTSTRAP_BUILD_NLOHMANN_JSON_H_ +#define BOOTSTRAP_BUILD_NLOHMANN_JSON_H_ + +#include "buildcc.h" + +namespace buildcc { + +void nlohmann_json_ho_cb(TargetInfo &info); + +} // namespace buildcc + +#endif diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index 1e70b401..8e72841d 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -20,16 +20,12 @@ namespace buildcc { void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe) { generator.AddPattern("path_fbs", "{current_root_dir}/path.fbs"); - generator.AddPattern("custom_generator_fbs", - "{current_root_dir}/custom_generator.fbs"); generator.AddPattern("target_fbs", "{current_root_dir}/target.fbs"); generator.AddInput("{path_fbs}"); - generator.AddInput("{custom_generator_fbs}"); generator.AddInput("{target_fbs}"); generator.AddOutput("{current_build_dir}/path_generated.h"); - generator.AddOutput("{current_build_dir}/custom_generator_generated.h"); generator.AddOutput("{current_build_dir}/target_generated.h"); generator.AddPatterns({ @@ -38,13 +34,14 @@ void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe) { // generator.AddCommand("{flatc_compiler} --help"); generator.AddCommand("{flatc_compiler} -o {current_build_dir} -I " "{current_root_dir} --gen-object-api " - "--cpp {path_fbs} {custom_generator_fbs} {target_fbs}"); + "--cpp {path_fbs} {target_fbs}"); generator.Build(); } void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, - const TargetInfo &flatbuffers_ho, const TargetInfo &fmt_ho, + const TargetInfo &flatbuffers_ho, + const TargetInfo &nlohmann_json_ho, const TargetInfo &fmt_ho, const TargetInfo &spdlog_ho, const TargetInfo &cli11_ho, const TargetInfo &taskflow_ho, const TargetInfo &tl_optional_ho, const BaseTarget &tpl) { @@ -119,6 +116,9 @@ void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, // FLATBUFFERS HO target.Insert(flatbuffers_ho, kInsertOptions); + // NLOHMANN JSON HO + target.Insert(nlohmann_json_ho, kInsertOptions); + // FMT HO target.Insert(fmt_ho, kInsertOptions); @@ -217,6 +217,12 @@ void BuildBuildCC::Initialize() { TargetEnv(env_.GetTargetRootDir() / "third_party" / "flatbuffers", env_.GetTargetBuildDir())); + // Nlohmann json HO lib + (void)storage_.Add( + kNlohmannJsonHoName, toolchain_, + TargetEnv(env_.GetTargetRootDir() / "third_party" / "json", + env_.GetTargetBuildDir())); + // CLI11 HO lib (void)storage_.Add( kCli11HoName, toolchain_, @@ -268,6 +274,7 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { auto &flatc_exe = GetFlatc(); auto &schema_gen = GetSchemaGen(); auto &flatbuffers_ho_lib = GetFlatbuffersHo(); + auto &nlohmann_json_ho_lib = GetNlohmannJsonHo(); auto &cli11_ho_lib = GetCli11Ho(); auto &fmt_ho_lib = GetFmtHo(); auto &spdlog_ho_lib = GetSpdlogHo(); @@ -281,6 +288,7 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { .Build(schema_gen_cb, schema_gen, flatc_exe) .Dep(schema_gen, flatc_exe) .Func(flatbuffers_ho_cb, flatbuffers_ho_lib) + .Func(nlohmann_json_ho_cb, nlohmann_json_ho_lib) .Func(cli11_ho_cb, cli11_ho_lib) .Func(fmt_ho_cb, fmt_ho_lib) .Func(spdlog_ho_cb, spdlog_ho_lib) @@ -290,8 +298,8 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { .Build(tpl_cb, tpl_lib) .Func(global_flags_cb, buildcc_lib, toolchain_) .Build(buildcc_cb, buildcc_lib, schema_gen, flatbuffers_ho_lib, - fmt_ho_lib, spdlog_ho_lib, cli11_ho_lib, taskflow_ho_lib, - tl_optional_ho_lib, tpl_lib) + nlohmann_json_ho_lib, fmt_ho_lib, spdlog_ho_lib, cli11_ho_lib, + taskflow_ho_lib, tl_optional_ho_lib, tpl_lib) .Dep(buildcc_lib, schema_gen) .Dep(buildcc_lib, tpl_lib); } diff --git a/bootstrap/src/build_nlohmann_json.cpp b/bootstrap/src/build_nlohmann_json.cpp new file mode 100644 index 00000000..7bf5ce17 --- /dev/null +++ b/bootstrap/src/build_nlohmann_json.cpp @@ -0,0 +1,34 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bootstrap/build_nlohmann_json.h" + +namespace buildcc { + +void nlohmann_json_ho_cb(TargetInfo &info) { + info.AddIncludeDir("include"); + info.GlobHeaders("include/nlohmann"); + info.GlobHeaders("include/nlohmann/thirdparty/hedley"); + info.GlobHeaders("include/nlohmann/detail"); + info.GlobHeaders("include/nlohmann/detail/conversions"); + info.GlobHeaders("include/nlohmann/detail/input"); + info.GlobHeaders("include/nlohmann/detail/iterators"); + info.GlobHeaders("include/nlohmann/detail/meta"); + info.GlobHeaders("include/nlohmann/detail/meta/call_std"); + info.GlobHeaders("include/nlohmann/detail/output"); +} + +} // namespace buildcc diff --git a/buildcc/CMakeLists.txt b/buildcc/CMakeLists.txt index a034aaef..eede4309 100644 --- a/buildcc/CMakeLists.txt +++ b/buildcc/CMakeLists.txt @@ -14,6 +14,7 @@ if(${BUILDCC_BUILD_AS_SINGLE_LIB}) fmt::fmt tl::optional flatbuffers + nlohmann_json::nlohmann_json Taskflow CLI11::CLI11 ) diff --git a/buildcc/lib/target/include/target/custom_generator.h b/buildcc/lib/target/include/target/custom_generator.h index 327cd914..c7558757 100644 --- a/buildcc/lib/target/include/target/custom_generator.h +++ b/buildcc/lib/target/include/target/custom_generator.h @@ -86,7 +86,7 @@ class CustomBlobHandler { virtual std::vector Serialize() const = 0; }; -struct UserGenInfo : internal::GenInfo { +struct UserGenInfo : internal::CustomGeneratorSchema::IdInfo { fs_unordered_set inputs; GenerateCb generate_cb; std::shared_ptr blob_handler{nullptr}; @@ -99,7 +99,7 @@ struct UserCustomGeneratorSchema : public internal::CustomGeneratorSchema { for (auto &[id, gen_info] : gen_info_map) { gen_info.internal_inputs = path_schema_convert( gen_info.inputs, internal::Path::CreateExistingPath); - auto [_, success] = internal_gen_info_map.try_emplace(id, gen_info); + auto [_, success] = internal_ids.try_emplace(id, gen_info); env::assert_fatal(success, fmt::format("Could not save {}", id)); } } diff --git a/buildcc/lib/target/src/custom_generator/custom_generator.cpp b/buildcc/lib/target/src/custom_generator/custom_generator.cpp index 7ab3065a..6e466b1e 100644 --- a/buildcc/lib/target/src/custom_generator/custom_generator.cpp +++ b/buildcc/lib/target/src/custom_generator/custom_generator.cpp @@ -136,10 +136,9 @@ void CustomGenerator::BuildGenerate( [&](const auto &iter) { gen_selected_ids.insert(iter.first); }); dirty_ = true; } else { - // DONE, Conditionally select internal_gen_info_map depending on what has + // DONE, Conditionally select internal_ids depending on what has // changed - const auto &prev_gen_info_map = - serialization_.GetLoad().internal_gen_info_map; + const auto &prev_gen_info_map = serialization_.GetLoad().internal_ids; const auto &curr_gen_info_map = user_.gen_info_map; // DONE, MAP REMOVED condition Check if prev_gen_info_map exists in @@ -293,8 +292,7 @@ void CustomGenerator::TaskRunner(bool run, const std::string &id) { if (run) { rerun = true; } else { - const auto &previous_info = - serialization_.GetLoad().internal_gen_info_map.at(id); + const auto &previous_info = serialization_.GetLoad().internal_ids.at(id); rerun = internal::CheckPaths(previous_info.internal_inputs, current_info.internal_inputs) != internal::PathState::kNoChange || diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp index 3c919d30..0703046d 100644 --- a/buildcc/lib/target/test/target/test_custom_generator.cpp +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -51,7 +51,7 @@ TEST(CustomGeneratorTestGroup, Basic) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 2); const auto &id1_info = internal_map.at("id1"); CHECK_EQUAL(id1_info.internal_inputs.size(), 1); @@ -82,7 +82,7 @@ TEST(CustomGeneratorTestGroup, Basic_Failure) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 1); } @@ -105,7 +105,7 @@ TEST(CustomGeneratorTestGroup, Basic_Group) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 2); const auto &id1_info = internal_map.at("id1"); CHECK_EQUAL(id1_info.internal_inputs.size(), 1); @@ -138,7 +138,7 @@ TEST(CustomGeneratorTestGroup, Basic_Group_Dependency) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 2); const auto &id1_info = internal_map.at("id1"); CHECK_EQUAL(id1_info.internal_inputs.size(), 1); @@ -170,7 +170,7 @@ TEST(CustomGeneratorTestGroup, Basic_Group_DependencyFailure) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 0); } @@ -207,7 +207,7 @@ TEST(CustomGeneratorTestGroup, Basic_Group_DependencyFailure2) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 0); } @@ -279,7 +279,7 @@ TEST(CustomGeneratorTestGroup, Basic_ProperDependency_GoodCase) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 2); } @@ -308,7 +308,7 @@ TEST(CustomGeneratorTestGroup, Basic_ProperDependency_BadCase) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 0); } @@ -337,7 +337,7 @@ TEST(CustomGeneratorTestGroup, DefaultArgumentUsage) { cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - const auto &internal_map = serialization.GetLoad().internal_gen_info_map; + const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 2); const auto &id1_info = internal_map.at("id1"); CHECK_EQUAL(id1_info.internal_inputs.size(), 1); @@ -437,7 +437,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_BasicCheck) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); } } @@ -475,7 +475,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); } } @@ -504,7 +504,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } @@ -524,7 +524,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } @@ -548,7 +548,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 0); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 0); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); } @@ -576,7 +576,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } @@ -606,7 +606,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } @@ -639,7 +639,7 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); fs::remove_all(cgen.GetBinaryPath()); } @@ -666,7 +666,7 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 0); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 0); fs::remove_all(cgen.GetBinaryPath()); } @@ -693,8 +693,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); - auto imap = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); + auto imap = serialization.GetLoad().internal_ids; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); @@ -716,8 +716,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); - auto imap = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); + auto imap = serialization.GetLoad().internal_ids; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); @@ -739,8 +739,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); - auto imap = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 1); + auto imap = serialization.GetLoad().internal_ids; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id1").outputs.size(), 1); @@ -767,8 +767,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); - auto imap = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 1); + auto imap = serialization.GetLoad().internal_ids; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id1").outputs.size(), 1); CHECK_THROWS(std::out_of_range, imap.at("id2")); @@ -794,8 +794,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); - auto imap = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); + auto imap = serialization.GetLoad().internal_ids; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); @@ -832,8 +832,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); - auto imap = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); + auto imap = serialization.GetLoad().internal_ids; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); @@ -866,8 +866,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); - auto imap = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 1); + auto imap = serialization.GetLoad().internal_ids; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id1").outputs.size(), 1); @@ -902,8 +902,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); - auto imap = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); + auto imap = serialization.GetLoad().internal_ids; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); @@ -938,8 +938,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); - auto imap = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); + auto imap = serialization.GetLoad().internal_ids; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id1").outputs.size(), 1); @@ -972,8 +972,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 2); - auto imap = serialization.GetLoad().internal_gen_info_map; + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); + auto imap = serialization.GetLoad().internal_ids; CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id1").outputs.size(), 1); @@ -1031,7 +1031,7 @@ TEST(CustomGeneratorTestGroup, RealGenerate_BasicBlobRecheck) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 1); } // Rebuild @@ -1049,7 +1049,7 @@ TEST(CustomGeneratorTestGroup, RealGenerate_BasicBlobRecheck) { buildcc::internal::CustomGeneratorSerialization serialization( cgen.GetBinaryPath()); CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_gen_info_map.size(), 1); + CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 1); } buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake index 207c6abc..a2c8c710 100644 --- a/buildcc/schema/cmake/schema.cmake +++ b/buildcc/schema/cmake/schema.cmake @@ -20,6 +20,7 @@ if (${TESTING}) target_link_libraries(mock_schema PUBLIC mock_env flatbuffers + nlohmann_json::nlohmann_json CppUTest CppUTestExt @@ -80,6 +81,7 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) target_link_libraries(schema PUBLIC env flatbuffers + nlohmann_json::nlohmann_json ) target_include_directories(schema PRIVATE ${SCHEMA_BUILD_DIR} diff --git a/buildcc/schema/cmake/schema_generate.cmake b/buildcc/schema/cmake/schema_generate.cmake index 9b6eadf5..c1a6b604 100644 --- a/buildcc/schema/cmake/schema_generate.cmake +++ b/buildcc/schema/cmake/schema_generate.cmake @@ -3,12 +3,10 @@ set(SCHEMA_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated CACHE PATH "Generate set(FBS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/path.fbs - ${CMAKE_CURRENT_SOURCE_DIR}/custom_generator.fbs ${CMAKE_CURRENT_SOURCE_DIR}/target.fbs ) set(FBS_GEN_FILES ${SCHEMA_BUILD_DIR}/path_generated.h - ${SCHEMA_BUILD_DIR}/custom_generator_generated.h ${SCHEMA_BUILD_DIR}/target_generated.h ) set(FBS_GEN_OPTIONS diff --git a/buildcc/schema/custom_generator.fbs b/buildcc/schema/custom_generator.fbs deleted file mode 100644 index 3c23fd75..00000000 --- a/buildcc/schema/custom_generator.fbs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2021-2022 Niket Naidu. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -include "path.fbs"; - -namespace schema.internal; - -// Relational input and output files -table GenInfo { - id:string (key); - inputs:[Path]; - outputs:[string]; - userblob:[ubyte]; -} - -// Custom generator regenerate conditions -table CustomGenerator { - name:string (key); - info:[GenInfo]; -} - -root_type CustomGenerator; diff --git a/buildcc/schema/include/schema/custom_generator_serialization.h b/buildcc/schema/include/schema/custom_generator_serialization.h index 5c51746e..13f66ba0 100644 --- a/buildcc/schema/include/schema/custom_generator_serialization.h +++ b/buildcc/schema/include/schema/custom_generator_serialization.h @@ -27,20 +27,67 @@ namespace buildcc::internal { -struct GenInfo { - path_unordered_set internal_inputs; - fs_unordered_set outputs; - std::vector userblob; -}; - struct CustomGeneratorSchema { +private: + static constexpr const char *const kSchemaName = "name"; + static constexpr const char *const kIdsName = "ids"; + static constexpr const char *const kGroupsName = "groups"; + +public: + using IdKey = std::string; + using GroupKey = std::string; + struct IdInfo { + private: + static constexpr const char *const kInputsName = "inputs"; + static constexpr const char *const kOutputsName = "outputs"; + static constexpr const char *const kUserblobName = "userblob"; + + public: + path_unordered_set internal_inputs; + fs_unordered_set outputs; + std::vector userblob; + + friend void to_json(json &j, const IdInfo &info) { + j = json{ + {kInputsName, info.internal_inputs}, + {kOutputsName, info.outputs}, + {kUserblobName, info.userblob}, + }; + } + + friend void from_json(const json &j, IdInfo &info) { + j.at(kInputsName).get_to(info.internal_inputs); + j.at(kOutputsName).get_to(info.outputs); + j.at(kUserblobName).get_to(info.userblob); + } + }; + + using IdPair = std::pair; + using GroupInfo = std::unordered_set; + using GroupPair = std::pair; + std::string name; - std::unordered_map internal_gen_info_map; + std::unordered_map internal_ids; + std::unordered_map internal_groups; + + friend void to_json(json &j, const CustomGeneratorSchema &schema) { + j = json{ + {kSchemaName, schema.name}, + {kIdsName, schema.internal_ids}, + {kGroupsName, schema.internal_groups}, + }; + } + + friend void from_json(const json &j, CustomGeneratorSchema &schema) { + j.at(kSchemaName).get_to(schema.name); + j.at(kIdsName).get_to(schema.internal_ids); + j.at(kGroupsName).get_to(schema.internal_groups); + } }; class CustomGeneratorSerialization : public SerializationInterface { public: - CustomGeneratorSerialization(const fs::path &serialized_file) + explicit CustomGeneratorSerialization(const fs::path &serialized_file) : SerializationInterface(serialized_file) {} void UpdateStore(const CustomGeneratorSchema &store) { store_ = store; } diff --git a/buildcc/schema/include/schema/interface/serialization_interface.h b/buildcc/schema/include/schema/interface/serialization_interface.h index df30f978..c09bdde2 100644 --- a/buildcc/schema/include/schema/interface/serialization_interface.h +++ b/buildcc/schema/include/schema/interface/serialization_interface.h @@ -30,9 +30,9 @@ namespace buildcc::internal { class SerializationInterface { public: - SerializationInterface(const fs::path &serialized_file) + explicit SerializationInterface(const fs::path &serialized_file) : serialized_file_(serialized_file) {} - virtual ~SerializationInterface() {} + virtual ~SerializationInterface() = default; bool LoadFromFile() { std::string buffer; diff --git a/buildcc/schema/include/schema/path.h b/buildcc/schema/include/schema/path.h index a98c3d2f..12406600 100644 --- a/buildcc/schema/include/schema/path.h +++ b/buildcc/schema/include/schema/path.h @@ -27,13 +27,25 @@ // Third party #include "fmt/format.h" +#include "nlohmann/json.hpp" namespace fs = std::filesystem; +using json = nlohmann::ordered_json; namespace buildcc::internal { class Path { +private: + static constexpr const char *const kPathName = "path"; + static constexpr const char *const kHashName = "hash"; + public: + Path() = default; + explicit Path(const fs::path &pathname, std::uint64_t last_write_timestamp) + : pathname_(pathname), last_write_timestamp_(last_write_timestamp) { + pathname_.lexically_normal().make_preferred(); + } + /** * @brief Create a Existing Path object and sets last_write_timstamp to file * timestamp @@ -103,12 +115,21 @@ class Path { return GetPathname() == pathname; } -private: - explicit Path(const fs::path &pathname, std::uint64_t last_write_timestamp) - : pathname_(pathname), last_write_timestamp_(last_write_timestamp) { - pathname_.lexically_normal().make_preferred(); + // JSON specialization + + friend void to_json(json &j, const Path &p) { + j = json{ + {kPathName, p.pathname_}, + {kHashName, p.last_write_timestamp_}, + }; } + friend void from_json(const json &j, Path &p) { + j.at(kPathName).get_to(p.pathname_); + j.at(kHashName).get_to(p.last_write_timestamp_); + } + +private: std::string Quote(const std::string &str) const { if (str.find(" ") == std::string::npos) { return str; diff --git a/buildcc/schema/src/custom_generator_serialization.cpp b/buildcc/schema/src/custom_generator_serialization.cpp index e6b8e119..8cc22aa6 100644 --- a/buildcc/schema/src/custom_generator_serialization.cpp +++ b/buildcc/schema/src/custom_generator_serialization.cpp @@ -17,71 +17,35 @@ #include "schema/custom_generator_serialization.h" // Third party -#include "flatbuffers/flatbuffers.h" - -// Private -#include "schema/private/schema_util.h" - -// Schema generated -#include "custom_generator_generated.h" +#include "nlohmann/json.hpp" namespace buildcc::internal { // PRIVATE bool CustomGeneratorSerialization::Verify(const std::string &serialized_data) { - flatbuffers::Verifier verifier((const uint8_t *)serialized_data.c_str(), - serialized_data.length()); - return fbs::VerifyCustomGeneratorBuffer(verifier); + (void)serialized_data; + return true; } bool CustomGeneratorSerialization::Load(const std::string &serialized_data) { - const auto *custom_generator = - fbs::GetCustomGenerator((const void *)serialized_data.c_str()); - // Verified, does not need a nullptr check - - const auto *fbs_gen_info = custom_generator->info(); - if (fbs_gen_info == nullptr) { - return false; - } - - // gen_info->id is a required parameter, hence gen_info cannot be nullptr - for (const auto *gen_info : *fbs_gen_info) { - GenInfo current_info; - extract_path(gen_info->inputs(), current_info.internal_inputs); - extract(gen_info->outputs(), current_info.outputs); - extract(gen_info->userblob(), current_info.userblob); - load_.internal_gen_info_map.emplace(gen_info->id()->c_str(), - std::move(current_info)); + bool is_loaded = true; + try { + json j = json::parse(serialized_data, nullptr, true, true); + load_ = j.get(); + } catch (const std::exception &e) { + env::log_critical(__FUNCTION__, e.what()); + is_loaded = false; } - return true; + return is_loaded; } bool CustomGeneratorSerialization::Store( const fs::path &absolute_serialized_file) { - flatbuffers::FlatBufferBuilder builder; - - std::vector> fbs_gen_info; - for (const auto &gen_info_iter : store_.internal_gen_info_map) { - const auto &id = gen_info_iter.first; - const auto &gen_info = gen_info_iter.second; - auto fbs_internal_inputs = - internal::create_fbs_vector_path(builder, gen_info.internal_inputs); - auto fbs_outputs = - internal::create_fbs_vector_string(builder, gen_info.outputs); - auto fbs_current_info = - fbs::CreateGenInfoDirect(builder, id.c_str(), &fbs_internal_inputs, - &fbs_outputs, &gen_info.userblob); - fbs_gen_info.push_back(fbs_current_info); - } - - auto fbs_generator = fbs::CreateCustomGeneratorDirect( - builder, store_.name.c_str(), &fbs_gen_info); - fbs::FinishCustomGeneratorBuffer(builder, fbs_generator); - - return env::save_file(path_as_string(absolute_serialized_file).c_str(), - (const char *)builder.GetBufferPointer(), - builder.GetSize(), true); + json j = store_; + auto data = j.dump(4); + return env::save_file(path_as_string(absolute_serialized_file).c_str(), data, + false); } } // namespace buildcc::internal diff --git a/buildcc/schema/test/.gitignore b/buildcc/schema/test/.gitignore index a8a0dcec..7628df5e 100644 --- a/buildcc/schema/test/.gitignore +++ b/buildcc/schema/test/.gitignore @@ -1 +1,2 @@ *.bin +*.json diff --git a/buildcc/schema/test/test_custom_generator_serialization.cpp b/buildcc/schema/test/test_custom_generator_serialization.cpp index 909b980b..e92f69d3 100644 --- a/buildcc/schema/test/test_custom_generator_serialization.cpp +++ b/buildcc/schema/test/test_custom_generator_serialization.cpp @@ -4,8 +4,6 @@ #include "flatbuffers/flatbuffers.h" -#include "custom_generator_generated.h" - // NOTE, Make sure all these includes are AFTER the system and header includes #include "CppUTest/CommandLineTestRunner.h" #include "CppUTest/MemoryLeakDetectorNewMacros.h" @@ -24,56 +22,24 @@ TEST_GROUP(CustomGeneratorSerializationTestGroup) TEST(CustomGeneratorSerializationTestGroup, FormatEmptyCheck) { buildcc::internal::CustomGeneratorSerialization serialization( - "dump/FormatEmptyCheck.bin"); - - { - flatbuffers::FlatBufferBuilder builder; - // Entire std::vector is nullptr - auto fbs_generator = - schema::internal::CreateCustomGeneratorDirect(builder, "", nullptr); - schema::internal::FinishCustomGeneratorBuffer(builder, fbs_generator); - - CHECK_TRUE(buildcc::env::save_file( - serialization.GetSerializedFile().string().c_str(), - (const char *)builder.GetBufferPointer(), builder.GetSize(), true)); + "dump/FormatEmptyCheck.json"); - CHECK_FALSE(serialization.LoadFromFile()); - - fs::remove_all(serialization.GetSerializedFile()); - } - - { - flatbuffers::FlatBufferBuilder builder; - // RelInputOutput in nullptr - auto gen_info = schema::internal::CreateGenInfoDirect(builder, ""); - std::vector v{gen_info}; - auto fbs_generator = - schema::internal::CreateCustomGeneratorDirect(builder, "", &v); - schema::internal::FinishCustomGeneratorBuffer(builder, fbs_generator); - - CHECK_TRUE(buildcc::env::save_file( - serialization.GetSerializedFile().string().c_str(), - (const char *)builder.GetBufferPointer(), builder.GetSize(), true)); - - CHECK_TRUE(serialization.LoadFromFile()); - - fs::remove_all(serialization.GetSerializedFile()); - } + bool stored = serialization.StoreToFile(); + CHECK_TRUE(stored); } TEST(CustomGeneratorSerializationTestGroup, EmptyFile_Failure) { { buildcc::internal::CustomGeneratorSerialization serialization( - "dump/empty_file.bin"); + "dump/EmptyFile.json"); CHECK_FALSE(serialization.LoadFromFile()); } { buildcc::internal::CustomGeneratorSerialization serialization( - "dump/empty_file.bin"); - char data[] = {0}; + "dump/EmptyFile.json"); buildcc::env::save_file(serialization.GetSerializedFile().string().c_str(), - (const char *)data, 1, true); + "", false); CHECK_FALSE(serialization.LoadFromFile()); } } diff --git a/buildexe/CMakeLists.txt b/buildexe/CMakeLists.txt index 6d4f9a9e..73bc7d2d 100644 --- a/buildexe/CMakeLists.txt +++ b/buildexe/CMakeLists.txt @@ -17,6 +17,7 @@ target_sources(buildexe PRIVATE ../bootstrap/src/build_buildcc.cpp ../bootstrap/src/build_cli11.cpp ../bootstrap/src/build_flatbuffers.cpp + ../bootstrap/src/build_nlohmann_json.cpp ../bootstrap/src/build_fmtlib.cpp ../bootstrap/src/build_spdlog.cpp ../bootstrap/src/build_taskflow.cpp diff --git a/cmake/target/json.cmake b/cmake/target/json.cmake new file mode 100644 index 00000000..bc524c55 --- /dev/null +++ b/cmake/target/json.cmake @@ -0,0 +1,3 @@ +set(JSON_BuildTests OFF CACHE BOOL "JSON Unit tests") +set(JSON_Install ON CACHE BOOL "JSON Install") +add_subdirectory(third_party/json) diff --git a/doc/software_architecture/buildcc_interface_lib.PNG b/doc/software_architecture/buildcc_interface_lib.PNG index ec3e12435751789dae816a7bf9e8cbbe85db6435..332d0398b66ab2229a0339e7c2f217d49d1e06b4 100644 GIT binary patch literal 171128 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%0DQPC>zD`PY2d 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

= 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 T$@E$sV&wD#_T^bkT9Sx3*4or+F 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 qRVdnx`dtxWV!!W)r6UkT`DMPyZhrX0L+) diff --git a/doc/software_architecture/buildcc_single_lib.PNG b/doc/software_architecture/buildcc_single_lib.PNG index 9038de0b052dd5f2849f2f8a1221b5bf44c60b49..24cf51c9344ae028919b5d4d0d3e2aa319bc2d8c 100644 GIT binary patch literal 146121 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 boqhLDc=p?p*ibw9S*y=%K0PvP`FH;d3cF>$ literal 128739 zcmdpfcU;bU|NrGUxKGwOjzXk^XcrA5Wfzt9(nd-<4N+9KLj&zJxfwRBQR@^(Eg`I`LV9b}@w?~!1 z_-%s0_+{CDX5%+(B6A+&kJ*Ri_wHd#(f=ayV|*BlzZkN6cB-EY`Oxfi;Q7$x=0>5BJO-+g2mR5nSH#Iv_o=9W{YR`7&Q&=1DAu@Ys z^zHww7Ru?%K6CY%MB(<)4RfyR2UgCL79=Km8n# zI>ns%)4%c8GY@YK&iU7`&Ui-rfBKtadBJlpU$|h}RTH(=Zx$Y!hqXL-Q$xrWdk?P} z|6PL<-`wtX?OImx z!*DJ^z3i&a|NQHk>*U-R%KMJ@)Qe9w78e)a=la*H$vhJ?cJSsnba_t>CA$?@R4C4z zJ+CTSAviU(z^ry1?s12sqvL2p;Uw-_h;?*nfRKJoe|xF;!TStZ)qVT^9+8Yu3@vf= zxNzZDLBoQk)1z2o`7ZXKZ#E)bWpw5l)ni>XYdx2V%FJKB(YN?WO{s8ULT~duei0GX z8pE~u_-oJ9WZx7v_4(aHyX)e$l<>u=X=(hQmKr_vsD5{Cd(!pmzfVk#^>w!v7Al5G z#^Rs(0~K3erb>>q`MgRsc7OZsU4}_HyY!wt2gZATvK7V|@10!>8FCNsT#FYix_#); zC0XxZX3ktIyM6L2lPidO@ObxgS?{v~o7RH0F2{fVj)SXwCm9iof1NW&-rLE}uw$?wtJPK4dvJW9 z^1X9TgTbl9sv;f_?1QYgPNt>Vq@Kyh!k@Py^KuO*!}lB>O4hshNbb99gM~G%Sn0LJ zc^~`ooCa82JRUxi82a~TuF+>AY~MXK9{c*~&7+*K%FmuW|hj~hR$G=aFS{4a-Etuas1;e4e!AxOAPmU`wQvEVKZfGu;GKrZWHn~ zhHB%v4qdmk3|%zV`N-1M?;d)T%8?vlv{Vy*0}bTglk(_6Uz{MYy8PJiDsfhOaL%{`okhK91LKI;^? zWUb2{+3}}%I3+j zwf?@tKkvm~?waf$oynN1o9hs3{`}6Z6D>}Azj;*ca+|zcqDL!~zy9o{I|`=nqNA-X z5|3{7;_e}x>|?j8ZGXDtnTu<=x%nj}^;WK2X=iJ@L1KaByr}Izy#XOi+Sb;VW#PgG zFOIG0E@O@#U#9Iv)PWzX_0%V}_w?|)xw(yuj>cho@Jmq%k%XoHdx=%BvXqpRSD9A9 z4<9~UymDpIqst3RTUrcydwcr_25QqPx5YbteAQJJB-$bJ+HG=xbM3lyB`;rUySlov z{O3Q{!^6WR96#LQ(}-K@l5tQP5$@+(+_3@gHg8DMf0bf%`Qf8Sthj!>R&tz9hI#*& zFZD3(HryrbXv>x@#`h8e0s>Y#cdn9E)zP{6rMEerW2+;NfWZE_Yyws3X0__KcFoGL zX*DP)D4=gHEG+D9NVa*banbL8)AL1#FCVloUc49-^Oe@b%*-seuV8HP@4rW6wK&V; z&iniOy_rUDdbGW~yl^A_Sy@>It|P{>HL+?j=|)8hKE6oVjrdf5Zq{7iu&^YP@|(q# zm6dsdcVl8=R;*Yd*TeUyL>U|Y)6W^b$e0*@35i#Fd5r}w_sEI%?%nI;UW7D#NJUPoItru-)5wqPI*lZn>0m`Y*ry()R8h)4VQDThb7pd(PauaHz9- zx9S(w!zWK>7mRc)hx_ebuwX&|;GjA(OIa;Lp6UA^qyKphWg)D3nWVT)kr&5RFRzU@ z;XQqQ$xZ_u^c*mX)U2#c61^N)g|_zgwZg)}o}AkaydB;=oMqLRS$;a7{5&c;np_(8 z<3sjwqF1l&3;e0#qPw3O-eHdhlVr|tL7_SYxR2YLs;3u{ z^Vc#qwrHe;n{&PKIArX}$;lE9oe^?=e9KPH-+}!4)6W@&;-=J%X_0JjuI%j18nLR< z*uv+pADl0*?G6bI_4KkB($muu1BxJsQDdmP>Zq&Bi4QMsVOP5zUYr}J9_x*({{=rh z-c=(F|Du4i*=5A&s7TQMC;6ZL{$mZ7?9QD#*Rm1Z;gNmt-~l`0Z|_?(;eYO9o+C_P zz%l*Jn>VlWPi3j9syg)L50|vIw(5PdXf4R+Q@?Z2p-H6cMT!y2+_|DkY93dvsL04% zLVo7O7Y}6KN1&UIQr1CFfwzAC(Ok1;&F&2wHoRmp!CLy9KYw0QN~#@ZiDXP>S$kR1zSaPwgv-8dZ4v9OvFE6;c{?Iut zipbMZ`_ZEetHzBk{l(lJeaAa8%R;xF=s2an2LS2*U(1#)%RN1knxua(x~CzTA4`&D z)2gYe>OCTPc_F7i;w_(6k^nb1cU^+ET82e~W~jvRBQ`cR2c5s)q_MWMbFPp<-W`6e zq)vbcx&8aq4P=j*kwS>F1qPX-GC~K&7#EVrV7c^fjc2#M$%N@9aE3n@nJ{ zU`g)apaaKtSG~fCFTqGKJexLc(n!>)>pZaItev9Ubc7AxW+n7Dxu;r;qVcHiGC0*5 zsmZVJoX0;Gt(_3Bv!%TAEw72Wj1F3=aZHSlQ@+{0eLJ4F_Vr-BJ3+eJcs3qBKDo;a zIBKeydxzeKyLAtC)k@fRcnIm|MtXR79Oh_1Muh8P<2@Z(U52}WwX_C0%Io4Z_%qCE zFD=>leZ3Z!BZ{NP1?l$ErEiK(OJ~HsKq9J1E%mJ%ph2V{d-M*JE zUq-q;qHOo#=GU($aTSHasmXhkFFQL;L$}z=03h8j)r?b@71T+;j*OL;pWpueeGGzX zN%f7aHWdftd~T&MvF%?tHXqx8@2q-oeoor_-&3-(v}&Uj+Pk`VPn-@agJbiG6GTlMz=3I??jvrNF2Z%0!8S(GKPAUG^sXV;q&IQ1`nR~n^8t;`IwK%A{ zf4>L83xu_Zh`-81wy1r}Lt-{PA8=>LugjLVTzwJ5GB9uLLR5*@xn|9p<#*sO#$64q zWCIQ4F9Ob#%m4V}kKB`=Z$}n>NwI0k%eg6Lb{i=)UWF->JKS;#Ybmv5>(+Q&&Ju1v$Jcl9S}v~6(V?DP=b<<Z42Zk@)$RELlRgh7ca7!n`!H8Ay%1Y1giEWMx!Y8peBgdTL;)a6_wP z&1)jBARi{cdE-v>wE$M$*x9hM9+i04<12q&y?Rv@mXhP)-1h8`sHmt|)hN0CPoHSJ z0o~W&>z$mP6Vf7?VK44Dj*si7aG6MfO{+UHerbz3d3&N#2bcHOIbutVJ=& zx@1WVySVus>=pa^gJ)1gc!cFgohaCdhO9w)zUfB^iPMgh&M? z&z>nG@0J@UR)lVihii_HOW)GVJ~kcm1tW$(ykxeu9jQw;G@LPGM#t)dxKj<_N9H^B zbMX1awFo{#jW&f{g;NvB8*N$=0t1%@?O#V*M!9q5LdgiA-r`4(cEhTYr9}`_74faF z?wv>`M+5Tcd3IwBVwKOmd-o>4WEI8&u5`EL-;2{qw!X2SaZn899@$8LFUm@t9J?sj z(JpSQSLw2`v9Ul7S_cnCAd$4cd#A?trzq9Z_U{!b>)g6^ix53vLwkFB)Qp+4O`ly~ zWe%^rl03KZcTP^5uonSa^84bl0Zg4@0tH8nL3ZO?94`pjV7 zzU}b#@o#u2itWg)SjeQ^yz!^AZQos@y7P(q5{t?(sW`P5uh|P$+-b=_#lL?2-93)# zS3N!J;8Pja%@P+cT`D;uLe(TYAg1$Bw{%z33Y44PIWGc^JGUZZaLEq!G!!x;-}m-f z3*BUsF*lC`>^Z&n%BRZhQ|fRAf^(?IjQRh_L_k3Z^E-cjx0(KN-wkkpS7}F;GI!Nq zoV!FlR(0+1&ZRK)2P=pKbMe%0MwjR0AS(O&zMbjkU9Zlj8m zKK9|ohD3vW9V(L%-C)2%F#K7wXU75mbw7{wsgtt3;_hDCS2&d{1uz8|B=lo`DeE}zkF=eNjZFx7O2&AOo5eOQym$8@YAD(@t`5%3=0cZ1?}3s zJHzp#4t;ZsQn)`XAk4X&R|>=k+gQ8V0Zm$im6CTlJ3B4g@72aA$$KNeSqU{8v-L?z zN~))sl&cooPmCT%^!-cMAEs~L)lo3kTk8L$wpPvB+PdBG+BZn-YiSU$hMgda}mi;S*k-t%xNvY%+c zXewKukYRy1_m^>8eDtp9TImsyScD}+`clo!gP%Sr zgB;+!v+G-NxhWtKo)85z6psuKNH4l%{09`}SknFsC2_g#KI9~R!~<^%8bDb$ZG!O} zv$+L1h^Jv7kk+Icmkv%0xAL!Ey^DZGYk^B$p_|+BzLw^0IoDaVOE!fQ(O_f}4GRr$ z?`rVap%+Hix;__i2E@n5SN}01Vh`vC@+x0$XL;h{saAQL?@JG7hG)g#W zf)od{VOg-C9$!qWb#~?)^YO2ryQ`U(t3NC6$HrA`%n?RVLiH=BprCP)g|)4tW1W&x zrDg3<@4dclOe6VR(Nl=A*h|xj7GyI^wK<8rTUi{tpYu`;VCXiHfeJMF%AefkgPqlJ z`u8%Qq^&?k<#ZXm0R!Sg;!p^c(10W4!3#`33uJHIWZkrW$!My77orxoEOL~{^uIiK zTHdeSu%S9cs^@sIfJwt0mEBmsmnB!=x8^VI-g;21q66OJu#pieXzP}wVen5V!~$S? z(gU_hx%-*r_d&We$odHr{0_*p^&T$Gh1N1rm;f0DuocacdUVSEJ>Yu1y2 z_mw@cy#@q(8*%gJ`#=UH;m%c3QK`VQ(9O2HywwwR#B=W5D}D56 zP2=D;-IeJ#u3tY`P@tVWj4;JDAs!|Ee&b_A@|2uIykC31dHzSXN&H%6AE9j%Ppb&;jJ>K4VH@>)h>>~;ME@Q}aUw@;0$ zg`e)fLS=e$o|Br(*q1udN=c^c#HjWYH-@|#VhVC|3#5$$nej5UDNO2=7^?9^y&P5K;d;>B zVuv69=VfE#a*jkjIeGb7crz;pN8+<*`|PXx05eek#c8KSqufffy4aX$r3=Jc+SwV! zw{6=t-Ip8SKGoILKV>5O8C4)fzbE$c7GW#AKVA&QwSJ+iK0;vwu9;|evjseh7zhur z*m`Hro*jMbF8mzD8`H>7o|l&w2`Jylxi!V8$oIyLTZl}>&CL^DT`ou-f}3<-8|2uv zd&QoiF9sUnDt_{W{s~XHw7+go?=;}pei88qkp{_@+y|@8`up#H!T4ctpY7)w*T83q zF~i%aItS08iBxq{+`>dCd-kutK5K4n?w(q>3w1UZ;X34x0@ulrqs=E;UD&reCdgb{ zY2{

wWC=TWMhIeTJ?hQHtT)5-)SQ9sr%Gxnl?JjuG+f$Bx`iSbGEcsXH;NMYYg% z!oy4B@Z|Uam96rqszF@%0Z7Jda~WOA5x;+{+vMp?GshrfF8~qsUB z!pFnQ#t-1{SW$!Mx^*%@gWi#s<}YvgJmi2H0hH4`MT5+!X%b9ltK*0DOG0p?LUZQK zLA-P8G?0E-(M8uA2>Azi5FJ0EAhGuhp> za7Rw2?K>G-Dx{zQ&`IkQZbqU`{Cr_zN?u8+f$R$_1_FuqufKK>e+`&o>>$SA`H|F9 zxp;YH$>lpLLM>Vr^!K?RJDMK+Y!k2nxmqqPO;QMWwQXtz-pKN zkt2~#a%$&i&wq|~hGqLU)J2G$#jo2kdADqNDftKgfCUFDYZL;EymxQT`!Gwxo=mI8 z65vJ{zUby0t5D-p8Jv zE>hn?cNeSrq_cA)Z(1G|TL?_;+6G_}Zyo!sZPih2N4PLmJfJ23FO4;fwETVXXpD%27ibea^;pI% z4G``r-_)A^Dv?kA5teGOMqZdW0_S(0o5YMu7H5X=?|_HF3H+^eTPDVagR^22P$L2l zmHqi%B<5?geWjGlUg0H4;0}t0JAiNL(em^2;gpU=!_nGlCi4WJokuTgYhNC7Q|oEk zl$roTSF_s2E0f4^>>DiuQEf&6u{{In)VWWS;#Y^Nc1L;+!2Q~_YlE_yD+K(E*~*%l zn$&abjG4@UtsqDwY~NlOIpvq(5fl<)={m1Wg0-r-Ss!J*(5A{$EIrR-)llMDgf;q( zf=NeTZexmqnHi8j|KO=T+HNsJ-WKP< zJJI`tZil;$$|BOyrb`^}KH?w{+&|V=*aQ61faMZ9`RQPJ=+=PNgjomczDEs9eVCzv z%aDc(_#}2Q)9Y*k2O{8a>>QY$ z!3^rK_m&Qki)?{drG}oX>10`lPEPc>S(F8CklCBc^1dRpRC94@$X_Sm#ImYjNK#p! zh-BT!$P`>=8-wsPG4ekAWyu-h8E&lE>wEJiABb^OTB{q?cYxm#M;-s5Iq&KZEr8zm z>K({-NSWwHSPOB6N}bYV4*$dtU0q$;CM6&7Tjx&?<`|0v`G$lfz+eMou70P-EidbxdFVeZ zXTI8?{@sDYB?hv-thOhikg&F-Rmoe2XN_e7cSsYvpE^Oe;t@ZN!?<8z>~dRD^#co1zs#^5x4|v)bsFa=I{R4N##u3V&(AddPj8*bkbR4SxOn zj?g2J>PV({@8 zJRm=z@k58^)l%P#kN^$q@XC>#@og1)o3f19HlC^|UA*pu;+AB$3d=2`?T&fl1#Hh6 z(Q=O>A`=bmnx-6kdE@z%8zX_lsXq&coGv&~k;3Wpz9RaHTQ_ZnN1KlHx1+uft-irH z^W9jZn+jZX(MN3n-A85h|VCCP!kNhkFx2a9O>$yAvgz%-#|WIk~Gj7p`YC z1!(U&=IB_lG2=VYs}6E~zM@y^Ydj!z;#$9m*jz?&=f{N_rqfF#0zD%QHhGY;&+|{6 z(7)%XfNY&soN8m6cpzmL`UG`t#Xdt7TlFBc1=Dr&$>6E%(!SMV?-V*iV zgxa-8a7M@a3lZ7$7fKCYM;kHy@RO@{DHl)KwhQFQo?z?mm#}gDbAaVk%e|mMtrzbW zx2Ko&gln1IO;1*HN`Eh}2uoQEZ||5pQ&;7NtNs zP~aoCRU>$&@7yQ4EmW)EL3zc+HIVnkmawE+=f6T5V7DmqH2C}dnSzl_CX@BgKbeSl z8h4a;BByy1Bc7L6mZiO>R2vq{E_w3q_trEPdb$4-9-uK#RE|-?1z&f;d&C9yVv9gb z`dWGGsH^)TfhM6lp^5iX2T_#LqRD+X97*yfRT=^5BLf_S3t@VD{= zNY(#IS}#aGbR%w{$3H=+24zAvxpuFMOrF|_VkvhD<8Yu^`V z-=mzaUvCla1q$i{WDu^)07&2wMbwQ}3QyW%-(iX%;EaA7xxadC-9?*dB>dYOrdz#Ie_BHd?*nLTYwT zazjoRH?7)n<;sM68&JN2?lh{-NGwJ(fAGN^PE!!L#L`JOprngh>D2beKoJ`9 z=GC{QGevx{O~}s`V-9yIsf#XQr1|UGG-V&!Rta25@WH*~>fe7WqkGcU)fJ1J5p?DL zmc`M70fs5U$ser;UaiZD5WlMCUuxCUe7jA^v&PUM=X&$0zWf-(Ei-JxO-U!a*yOzc z1wq#l3pW@&B^{hjy6Fv~4IH@k>7*XHLg1D={In|af;V_WIJxic?`U9}ibqqh3Kc{K z$PBa%S~~Y_g!DqU`(+x67>Ou!w%rvgIXo5YC zEOh?m+P2X<8rC!C`}$+sso4*dL4Ds0yLLJEqb~~G3Z1`vhz0L&`tenUWb3orT=H%* zmVFjSddsefvPP}=&8(v=$hjvmYY+gs2a2ThXE)2rXB`{>EF?fPYt9^gF0RNuEN`l$h+$c-Ym*-ZYuyQGn$z>JwK=ah zU?{cz)97Ja@G2Tu8#TBfwW0ymv@JhgW##9C^GI-#q@)v{+ z^_?@|7XIMGQgV>rlGj2u8?PChd^1Z>J9Q6z24K>>`k~?J(|IV#6Jdt_=5H!BTNZ*F zYoG`e8OfDD-e1b5KW5`L7EI+Rpt0Fq!PBq*JJ_nV@tlS+tgUA zA4~x)&1I@zeIilH@qrR6y2hymro3GDk9Tf=j)=6MR`gM`?Vafqsu?)YR4y?qRQUb- ztImZb0t3dAIl)GLn-C00yrkqZIr5&3e_WQp&kWSsRe0P%RDnb#ueB>n*#0ba@?e_Z zRQiG1x!gqgfGSKtATxb<;Wswj?~2O1vj{dNXs4wgeDKRaTjbl^#)gShMFwyAak*f0 zW~i}1ol?@6NH;h-I6O!1I2~x#swrCq;TNeR)AZ8YXCv!uDmInbpDLG(8Lv=NK3no? zu4Yb(-|$?yT_8EpBg{aACGr(WGUaP#B8WV7=y0}y)>hSB(=&0OEjv4#YS;!;Urbsm zHvN0DKI=#fxK1f7A;7>{7WhUTU`1Lq;>hBTFJS|pb0YiJWPbV@4ju<2f+1urcE^uv zpsGg8!PImey1G^`Q>9_H>IV=0HT*z8B)sTI=)QoVzJ&JPkV-fEZQR8@r=1dS=+3x% z$LF)%%1wn$_}7T7bpwBLVOp4Q)_W7DMEx*eV4}YfFTx5YM=eO7b-PDxbmqa@ZKIuQ zAka9C5^) zCtcH0O&-&3>~Vimo#$l#gY+R%$UV6=UQ766^F1w)jwrROz1PYMgx$K^?>vynRaiNT zHP$lLRHH=zCJWLG%8F{VS^({Z-H&cYsHJui1ccNaX46i)(>{+mk6mnE{;A=56t}S+ z9`oFjKB9RSBzlxg5nXj?muj&3hVCXjEX)F>Ol4F4eP-LY>5jdd%CUd{92d@?9PI&E z^51CPbO-USq4R+Eq;o+Uglp)5-a)3#1w5?2kswoHDD&)NdPr1mNO)z>yYYISPLYe{ zp{>FP+K#*Qm-sb?hs3mhnfsTv{Q1m{T*Zr!ZpisaYA_0heDJxNlC~silQvQ#>86PB zRg<#7Tj(V(=a@5VDbgzalUFU;6tBt@eb@fX+XOlwDl)ROR%yGqgj~?zvo+UDJF9Lv zqsl!#_QeXz2}vq-%E)1e14VCFyVz2G&{Ie_QXjt`y-~L1%Stkx*#dQJn z4l)7H6OV>DJ-t4Z2=F+tc-gX8RNckbhi3lr3;hF?<4|w2E)jId=c}~OcxOVu3P!Mt zYJ3RPfP(o>o$85uc|@^gzr4I!mUS};$(U9xf{H zJN{tYz^%;rWyn;;$Nq~>E}yLpcMJZuL`Y8=?8x9?t&+v(w@=o(jz4^b%tAFi(JZ5o zY$Iiw9q>=Mn%1nh^L=HXaLBsc1W9K!DzI1p^YkDxJjSg?$pBQJJ;-;Tv`^jHlW?ojm{^Q zb#H94UpTFsaN&3=D6FX0uMbkIqDnGIu3IYec1wW!Jwa=OqLMz_b%i}Xt!5Wp3fCvU z|Idkmul}tAEKDSdu8al)Lf@2=1P|QZ0q@x)p;=H7zCD>#%@9tYU#&V_MO|3Ia&z2l z(B-efG0{nGDJgyM5j6|9k4I1`gg@^d(oTp!H;-{~u!KLEdeTU~LPM?5&nzlOn`DMe zCbqu+Pg6obWlwsO%;%0wgG2StoSa>iR|i#DeQXjqaf zgCiG}SY-FiIsDnjYt;!Gd@@i^RHM!(q=6D~sm@m)Akw=#fu|u8s7CEqcU#(B)lj&Q z(>!OQXnTAf%lRCRnCzFSNq((e7kMXH*Yz|5=v{nzjWZd1Frf(bhVL@n1Qjq}=gyrQ zL{%G5V!c$_Nq>D-X`AmrMr9t$2B(RB2id$!&YP&f1=c2n^1PnMBcyR++r(fkh;IK| zK_$U?25Obsn#Dc#IUL-D1FV~Z{~&fSCfxNEU*4>%zl%}v$ktoNLMHK zL|+o^6zGts0?nO}ro}>-MYTS=sENnQQy(^<%wNvYvq0KOlEoRzO%+-1kgg+}7MQsVrva0?ShcK<`(2ZT*(cb|;SOjQ z#-MlXU-H@gVRf|%G2;a1pw*{4MOy_FfLRW!{9HA$j7#3KCYsC`J?XuBdw|%*T7{r~ zYF6dtTB3nG51kU_8zysKYEq-3B1DnYUWJ^((qXYIsc(jeq=a9-f+7|*7qwiNM$Nal z3S-s|4ScX(xkPUDZrg%&GLs&{yl6L*c!YGg)HOxFapOIyq_ng&*RhYAa&mLykhml( z8FD)yUn9W+HT1#1b-&7pufD;BLh|7G`XqgRKnf@qUfrFS(^*^RS&O8Bep@6Ot_4KP%1Rg$XP!chD)^+RhN)fKT)}So8WTBp%&7I;oYy{Sf6spTP z)&zq;;=$;Jfq?-^qhQL4phcNRvV5b%=@DagvLfBK57?~VN4onR&*OVApH4IocmnpW|+KM+V^XJ~gtr((= zrjdG#A_tRsL@ltW;Nj_lNK)XSNnQp1QZUuv5b-OZK}Mm!5J%&ZVi7*KUO>sV#i&$L z=}=5P>j}?u6#)&E4fnQGG>33!t+<%Oxp>G)+KeI;+@|i{2^;zt=wmhX<)lS@qtS~d z%K?xgH3b5!5OYnl-?^|_lYBS-r^14ZPk6pfI?5Y0w4$QZ@GCDb?nfCS5W*0o2?3@C zZ9~Llu>It?6UyWJt1a5auSz7>%8#apOgTO4=}UMoSjH}0tfm9vJ_6Nmz^KIcWRXGL zIq2r(+h0h#Ag(oV_I21vODVc)%c~+Xtd)g)gEvF`>YDeCg}{sGg=U=e3i&g^j^Fl( zpmE#Au60=hM>Jlfn%ZWim-W31>1i8ppKPkH7|Cf$(zOmK?>XS4Feml#^SdF~IV!l1 zH;!~Te0(Ji+Ozp^59?5Va7YYm$A%O!<4L_7Xn~~b`B}DZ-J1XPtvk^(Nrr_<5PX<{ z)w|;t|MA7+>_mxhDLZ&PSRr=mJad7uYjD-3R4CX18_I>6{PL_3@5-Mrn%IY~> zT=W2J47zw);Vxf-Pi@v@8lR(m2 zz52iV-3%&=1Rm78yP>g&af>Xk6nDe{z6L1^nv-{1wuea3s?hl-f@^_g(aF@GT7abKTsVO~C_! zBMK`ktZv#`2k@Kr+qzn`Z{papeU`$43gHun3N=TJD=glc8RS^nzG{UCo*o|xT~lxe z)G4pN(Z8o_;hFN!7*0Vqj2Hli#fwQF0f{xW_?gTf7ST}PataDIzBOweb@H@7MW5|C zS}yTT55@Q`UiL0oyQZ*9)BgxR{DWjm%>^#OV>?!n$P|Et)Zrdpsyvv`Q%2&3&U7_~ zX&`Jlr8#C_&E8w;YuHx-riT>X)W|Lz?{`OkIUar9r5vTVp>~e|&YeJ?tO32uA%OPf z9I*#jZtf2nlH4*SXdK=Yq-!gbT%5P1fu}RiDKWfZh{q$rf{pt`#kB#x@%H1+)u@Xth7JG+37wL;1J{c?Sm+YKK>Rjq^y6uJ=htWFknSCPKuagjMhtVz z@2-h*uikK#dhe8s#7=#&%>Vp!IaSr9xo{BhU4=f5^Fa9~R_qvs5cIL8 zp|DZnY8|N~9DAE$p~qXw5%uiD$B*Jp{YM}q=|Pi%YICrGo?aJ4UIPQulC`)^xwt@) zj>^XmWT%mXz#}O7JJD2q4jxn7p;MVgInl0O+aq@G9E)Yp+O6`e%_1><*em9 zQducef=eb1FHiv$yznQ8Q_d(*FBZZKG4tmR- zJ{oX-2qLKE98vo*^HNKFIMC{^^xnvh#t)JzD058uMq5)wgMU`a3N+fFfQUeDWaoGi zH!%=CMZI_h1-r6XM0m(HuMq@;DVRZ1w>VVA61J&^R-*%2L*N?ap(@Pk+NCNB_*M(d z9Y;bX8p|k{_@c{P^Ku0XSS zgGkzpC>;+wCYqw!wpXs=qwD!|=RCZAI_(&QyIvPQi`s}DH_RSDj2pp!StbCma zBnYIwG*0158mLKxoM!Pd)tCm@CMU)`y=E=9gWq|s*rE#MdX<`zR1_v%cT=cFD-Fcy z=V%X|9$xB4qy+=p1)_{6w>@}0Ui9amo?aIuxzG@V zVtDjRqYb?ZEi607_nG(gO(=S(3rdO;qSUc4-dGq2fA}G)=GRQ9f_>OHMBekyY3{?E z&QP0=k~zBkz7Yo<(Hx+8Vv-Yq2eI(MdbOi|s)vP$xsIP?G7p4e_Q-SThF#RJnJb)k z&>>`zD6AWU5Hv0bC^P!?-L++mbH9)x(Hs*&^~r|GSW}A!=VsC1NOej=3z$o>Z7rvx zerN%Vp3bA{OXu#vv)Hri4TITbi*)K$^{r>!3kfKfND&&aUE9-|qmWi=<(a_wUeeIO zqRlUv=bBB9!Yh7L7Q>24)((pRt@;EvmJ*GSo}<)R)dHc<<>Zo1dRo$m+^{~(>QZ8v^4)=F|okHbT?Jua? zh9L<~PEOQyWoV;(1iL`ZArj}q$WW!ZVi{RM;jC|**i{qSII;~-O~0aQhhhw3e7EPO zmh}=|ZwQ@06if;vqFlA`GG*NCOfRpciC{&at9>=HWcpd5dO4Nksvk z>h`pfu5=w0q9hcd{y0e5dC?OOaS5M>3UklD+B!rR-MX#8fksR?=&&7kC}sw$B*&+n01xkgWKlJnH?%7%f7 zuTxV7e5+$Fd~)PjremtAxTWodubi&QNLkqe$C{4(4Z)9=Hd?kAnb@?P&Kz#pdMI!~ z$)=(Ob`=}gRksLU)=*p}F)?}4?aOF>{wCdhmEFhh83;|j$T21AdLV)`FxWKou~Cb9 zS0wnDHV=WN0+@8}?d=_fR*1&gNPRQ!QEx3O*rdX#iN2c>$KxQQI_ywk6*u~+uQ0h{ zf*J2n+URD;c{(Qk^pu)3$2iG<&_X820b&9&dj+OX?_B0~hQ=if$dI4l4?@v4`9uD& zSusduyvBs)fG({gAJ{pUnPFTTkvo89Ic!vp{;I{0F@p6Ybcb zk9XRw!J&15RIMi=3SELy2jHq_1>cfFgW-G5L*{UKIb;OAVT;+QYgWVh=r=&xNp=k* zlQ*!Ed=e5m_zcaH5b|(P&EXXis)rB(<5;l(_ogUSscnmkZUQEP;=gpT(rr==utXCt zIk_E;CNM}{7%<0_Ex{7Bzj<@WLDTOusqvtWse+V`CS95K)@pz3J!0IhsP$3P*TTLp zGj_GuR2Dq66tx>cUQAqJ;OLM;jf>I684)G6$BtEjQuhrCibb~Q0d=ndnS|Ksug5^C zXhM4_!>zdte~`10jsy2g{C*w$&kvu0#;O=M)w$=Jl}D(4#?&kjJGHdoeb0)EWl3TS zDVwKayfWJR>7W&*`k$@AW2l0AgnDLY{#frl6H(VuB`}pxHFGvh+&pWTJdlW{Izn{} zfncAKP|V3fIWCM@E2mSZNTH@N>F^wKBd3!mJ3nT%)`P1~q{jry)hVzWw5bkw0Utj< zKWIwmNQR}M7wjBf-=9Hqu;3OOs9}d+(*%pmQH?EhI0kjU&}iwd(=trFK2zwm_2Z{c z!Lk^V-~!ReJD5aK@11fF z)CRP$^d>0p%s}2txQwQoRE8x&ezZLFdm>lY$;`|o97AndxFnQ=TIeHJQ?mroGjNF8 zKndJDY853|Sq&+9P~Uu)-cO$;P^qjpteX+^?s$P4X$olK2lhnm6pX0#Ac!h!YWi23 z8S_Co3sUk1Ml=C4X|54uq=KfVrcBJTk|$53LCMu&o=6NgK{3SRU3|8;_aYMD1IS^} z=RAQ(%ycl*;?ew6vDG#HdV6A?%~-GVJ8r-_Z3g#UKtF8=DOG zHf0QoXrlTjtp>Wuq=ld^KJ~%2ZFHK0aYW~iprZ~rZUrLZ*3K2aXR*-`Jvond$0wKd zI}~oWgM>oRAnyPg5Gjz2vZ8H{&Ym_#R^oj7I6 zWW@->5c%}29g?cA0;qpKo(8tQjXy39lD`g zXQgR;N@l3mqwpfIj0+zRPu1>)QdH*CXg$!Y-=tA0qeKb38&z+$J6_?oC`X{Y2YeTP zr1YC050A2)T`GZ_Lyu-tM}Lz|i!ay($_4Oy8ZdeF_tkRjAQ=V>$5Zia5NXHh)Cvp` zVjtR8ALitICe={nYxO~4FN&H zIyB`$`|E%yr>+u;Z907e3$Y)8al<&LQBF<{AslMh(<~=S>MC&7l+YmMqWBE$GZ{5- z!St{n_6uX04de_k_le$tm9T33vJQ=PI$DFy(!e6{v@V&$IB~XmdaD0E9f?85Sdb*b z5$7vlfCIAH5U}G+?blyk*#N;bAm_SBLe#(6N_Au$3>9#PMLL&eeL*0++ zmC__koflb!&P}2g0?Zc$VN~IGyYRxi`8(<`(!UMvY>vW*Yq-(p5XMdN;kq6WKA6DA| zk+9Z?Ko8(`U;(UxR1Y+OYH4K!e~^OiMgd_+T&e(l<-#$?WB?k#R5@=U=&j+vXqU-S za{%-awW6`MeEj_KfSD!5#T%pyym1+{9p_RH0eMgzfusHH+tmOAfRviZnI|UfQ^599 z4#R6|;PeRt0x7f(4KVJXfBG$g9ZaGr3_y-r1!$2m*ie#dBfeI{NpL7rd`QR&eat5#mev9X?AH={ z_2LB~A8IziF1XR3s@GNAU5^1@15wYM@k^6EMobcyLXkn+rXoNR(}Q$#1>)J zI1Kw1iBFf7l*j>~iiWbGD}0BR3IY}=wxcWS;O#xYeI+F&swO7Uu#UBKToWA=Mcf!> z{Q*Wvx^_2wuDZ3y%JTTcg z59eO>0Hcy?Q8ykMUj$+vZtlHERbul836WxC0$o&P60Q#R?R=9w^=XWT@Yc^Cz+poE za8a@Ozkw!V#f&CWLoDgzaTF90uJB+`Ws-LrLU7m%bR;|&(8o|rJ;-ftVd3OCU%oJ2 zTO+Aa$XUtb5neD!v>Z=e7NPZb+~3ul9+WeP zUqmqtsg^&cd8%d45bH$JKmrZx_6HtxP|Ue2f)-NTqB(QsU{RixmnSy0I_}(gmQG)y z;S$`FKvq`I$B&70CErV)90fR!{_N$32)Au2jU>>dTE z&e*|v2p1R`c;5q(2^uiHoWcoYdkgp(o(hQ3pY)xiCP&VEQCHrwhe| zIm^KpFAb7a;D=```aw8yM_hvJWHuc|gK>LA$1TK-V+&=tA9&z2p-!OQD%^X5+eD8c z4f$2ewtFF_sc!%h*MJa?O-Rr5z=jCR6%43r7xJPfkIsxYAT^TsQHMok;0CVH#EHw7mq!T$6PwHQ znfCzEC@v66TvJf2wBnc+o@bSkp8gzw-T~#c%Sd~G+`fIv02@P~GKhb^l=;&MOT9{H zz4>0h9s!gd3&kPT)}D&HST)tvBXP!w0bC@?_3N8CAnhJ@ay?p)qvZHZ;oLOv3BtqN z;VM@w5-H5rmwIut=Cbi%><^|@O;tIXn#)6fIwv!GFX}2SC^0D;qvwjaU(?B@z7s<+ z>^M6BLjSE3AOImU*(g!0%!Xop?eHk)HL#}MG#4JA{W~MV@-&7#oUsgkAt3@_AW)}L zWi*YRp@1ehs%79L4Pn@I(&Cyi;v&$uFb83ud#&)xKQ{GR2}6oIVYtsh)v}^%i;#)J zj_-Cv#16_@gg1$J#7u?^_p<3tR>AEMagdOh=y(14UvuZqW%{_HdRtDs2Gw8VS*w;w4$P-Q;ea(K>hgr=S;u-P`3sShp6rJkUInqaR%i} zBa2KmzC5&`N^x;~(RunJTN*YeVwFMy#a4;;3-t?5Ya^!BqJTeQWW*$b0u-0s#lG3f zDc_?febWx?|tQvPpOlHu~9my z4^iKnh!yG;;mQ7cH4+$>l$TFmEzJb?iG61eoxxcDJFdHaCdOK+dYg`vCHiJKDh2mK zvu8Mb$rO;EuonqKDQNsK+CUD#VEF$sTn0ZTo>;%Y85R~6RK9}2XTE*=)}tcF0?EA= z?vjMsJQgG*P5t1Y06Ly)x`dUa4>K6|E$R5Tzy7*UF3(`Bw?KNlzn`R>bb=QS#7U27 zLxWV+@bu@4q}U~HjE-{vG{U(W=6=4uOMl!LeV*~@K5dPt2>LQ$t<2s$yeJdX1SGS> z1r0V*gVSU;Dr*oMJUDa?CiCAPIp_%Y0HUpznCUmYK5NKnfv4$wM&#$Eq4urxaZ(yn z-HWML;BXoufn>P)UzeIB$#UDrk5&$|`BureF%FuL)E5}o9Ner7@H2XFe2}(a>QNo| zQ~cQL9i*{DUwMPX{Quq&BVzyb;~3$XOws|%`wLW4@1%lP4KRaPBcRM9#>P>EGHDD1 zI2P{x(~t2v+MZjeC5utWV8204Y>qIyzto*hrbkO{%G&xS_LosIi2(Ev%J^1N*m|QjUenO9yjy zGDqnbXS9uw-%Kn)y%Ld+h-2kYGV>@59ja9{-IY-FlI&*)jdcr*2B7j0llb`*xCnK+ zmu2>le}l#mJ6f?KZCQb~j*dBwDwR0>_3k7@tHkDjy{rWjcn7oi|AcRKQ({C>nj%Hv zC+-69HMUnx=4iwsO1maPXb%ySgbK`4kyi_-$hkW<1_#ajK@D!2M$Ah+0AKh-qIE3UUKt>n&9K&}j(t3c`TJ z+s9W*Dk?VqxG>!$(7=vOiPQaj9XH;2C`+0{D;V4Hyv)_OL+vMcJNh%77KgKaj zM;um8fB4&f&Tzq^&rFHhv`GHrV@pfw>oxJAT;kTyt|09=K2NhX4v50cfqy=KutPvV zARR}q(&Nphb-K<)XJ#QqG*E!_@iB7ndV>>s#LQ~Aj7?0sY1WtcT-4(z;SZo)z3E?1 z6v&I)Vff&<20Fir?zozlRR*|i5TF1ehTRm~O)5fo5w|Et0p9-;AgAw2^bsJ#!NdRS zW3kF;QV&7B$AfDSD?}tHa78EQ)Yr??1mw?)vi?t6*Q{m8`j}Bgz>Ef?$F%1Qf!Lzk zM`>F%Ffcl%k+j>uieN!qqG;*AFU*-a-OOv-R8h4~`^XNz-=Qm<&cA2n$njop1g}Q@ zJR*}w1`w)t2q{4wQ-8_;S=3ctVsLUNh}63T8Nh=4W2Tb7gBpG7|2v*F!Xp7AZY0F| zZlYg3vAd?=dr2jUs>9kr@nStnK^hdHDjGdMYWmaJCjdonBfm4z)61sZ0oP%;HUK|? z_FapkT^c)m^xJ7B2|dXK5RN$T@WGEj_3gQ?P|R(*k&%%> zeI|S}Itsw+aEv;r^M8GeFA;i1Q-C8nlnK-U zdS|Pkje&5c=zqSS5YjlY|1^&V=1@!`s-~wgD;di8+o0B{97gyDBqTxp&+-0@9d!U; z`X!z7)OV3Vy2YVtr}>B~2(A-}IueIsNh9e^H|f6L(HT;YH8tsd zGa2$K96n4=HK0er~;(~&n4ov-R|qtt^X^_she%wxY4;QD!|v@KN|k33}tXAgpCw6al~VF=XYcj zcnb_0aM;qHaMtUjf1%0^b3x8Hf6Qngodykzpz&en=veRZ_xg`;h;RQN0n0>*^Z5~H zruSpV7TS+&3veOS3Pfdzd&^I^!c3^YA~OlrD1S z-v36ZunQM2#==`}ZnnK$&1({aL{3)+DMWn^z(IMe4~gRF)RKSQPt;vd`Jj`Qhkg%s zVFz?|EvOR=@y|4z+#rw5oK8%*Q99k1s$5E*sB*i0M!eIvHs=gQ%rIgHFgZm*0A^Ob z#iaDXgPrJ9(_lM^(y1^Z7O7yoU*1)JdS$--=gwh@Y`vw_y2B>n{37iMJy`)2{`SDO2bezR#*YxD*N3gP#Pm+W6MLY%1u9SfkK$1 zHW;ERKoC#G2W}XOt}mP%62_bNAtX>gtF5;;3FoFgojzla!N}%@m7}cn{g!j0Fnj~_ zei$F<^lC-foQ~7lm})A&Q9Nqe1n+f$HsK%dT`)-vTYz&BIu7%j)JT;AG-UWc0yM4X zeE|>1Ti|GJUzhUp^OG^Pt6wPbz#c{H_rP9KESo#`-QpY;lqw2TLOAxdQ0I=isx*n` z?k@TR75hELq~uzx`!{eTSA=wfri0t&ahzH}k64nz@_&@Q30ThC`}UnFWS%QyW+9X@ zBt@poQz(^;QHm0wK`KLJN`(+xNi-OeLM3E~kd!i%P)ZajQ}uiVq4$IZ}YPnBAzpI&KZa!&Y3f3q;M6d zK>D!1k?-iHgE);45`Tvpbs2n^3t#l(dHZwc&%=-TvTpP5&phcRJLHZb4PO7n$;v{z z|B}-U`PvNTK?IiKoko!?Ga^FH0Q3KMpq}z(^XAPbqocn%I44sDFfwO1q*dVAUtw}O zkkn(^BGG|D^H^!Uq2(*0E z5Gy20w%-A*B|9~>w07K2Fi{?Cb5x{w>;yrX1??98uI-Rj*Z(UK{cJC#zDdkuI{sB;sB7nhf(!<>}j=^?0dCRsgas zW?1qPaYNpP|2`~=Edn)vef%g0U0~q>vF^5&4J-64I7QeJ&SoVwh^#e;21S z#sl~7#xm*j>C=WUmw>IoaMuW(@>KTlu*S5_C@_vl&M-1sYS-|?ZYo$nCVPzVrRI^5 zQDJeY&SuV;Gw1I)l=rK9q8aKsAmVX*D7R_+X2h>Mxzv-~Bfbza#H-lq zSTAUW<&p4@&mn7j2x+QMooXm{nc z=FFS-vZNot{hsSd3Ds%@jBuWhi-7>9fRs4T!`O(;vA`9OoMH$LfKgR?i4cBaeYv&F zV!}5FJ^)rI-qNWGhykxMzdWFAbdAr_YfZ71iiigz+#U56-03b3j4<{fY>)DX4O0-h z2U|FCR}>;#R2y=hIFl*?idug-bC>n!@H3D}b?5Jc*-4;bzWPlR6y7d@#-;pz&|c?e zX69Txik~oCd?!RH9x>X)Zl7^~k?DEj`gDHJ#KgmBR%nRHjA1|4U{WUY&FSmWrOS<@ zn)^HngbSf`#{*m>vKO<;ubvF1}oU(l>357p4E7|k(LSGMh z=T!uQ&WV~u%FnxzAY`AX0z#7+dv@!V*QotPgeTNR;fGEsd?w;7(!S9Ll$>+0o2Mym zFW||k_E(6NPT9Qyl*NX3S>HviVz&9!=u}#I5tj@nl%=cmN-ebgE3(&O?ufL5p+6lWbjD?ko^;;*cyK)8V7cxb~aU}byk z@!3e>hwjqhwWpTl|p>e9QSAHrmZ6KWEnVt z?fBBvGEivU`Wu`7ZvNvDj3b_=iG4P(dh+etQ-SEMTUU#TjeS|Nc;Ji;UX_))Fi>pa z;~;XZu@I8tZ@|NV%@K9f@n${U=~G15%1|(;o;~36+iU6{d?ilN(HnHDzSc$3z(jw| z(S*UcAFdsp=q0qLa#Yh!OlXC+Tpg7$NujTHllU6N zRh2KRQZ2lP2W{F^9o&cyLT&oxTD?AE8Zqc-!xjl73~~J=QW)Vs|MQ;iW1b&T~N5@#zTq_3=c9uP&xkF+2uwmfNi|jN$#J?Zo zObi!-HLv@p_rRZvPXjOA{{~HG zS&8P&?Xu$d+-C+Luw>lUL23K1 z)@9f!jx-Qi_fgy!7i2{jO;&DT3JkJC%6PmbW&!(42-q21z2Du3rXbp&5;ArAJ5X>v zO`4rmIMD|(uc~w%A6hKlafPJ;84uOLa8}JSo)y73Rf;)rWCWXJM~oa;6u|tF^1)EOLy^FRKrXA&#?YynmBsnjQ&QT8+=FDa6eCVCjKU=Tk994P z*|%VwsA_n9_TMs&B7%ec5Xmy|0?iMOT3RixsY0VWWJ(#K!GZjxan1o;lL4e!&rs|n z7Ysp7_DOSjfnY?u1ZkQnz$;5j@LH28M={?bj-JGLScVv6A|A2MzR^x6M3ltGl6zI8 z;2;q(iPTrj*2!@Oc|QLJ_BiqV5)Z9+ExpM<1*jeS{YcqP)qYr*R3fQ78Um=K4KTbN z_p8^pg-b{s=fpCIPK8}YWT%$)Dfqng>uL%CX&m46k4Fb70cyBo=@gz1)2*FwsWR|+ zb8@_QCC6i7Oq2t$PY7%QMTy%Y%tiQr!tpRpDya&+Nzm+SDvyBl~Ioc$IDmLf2ftFj~o9B=lq_226ECCNmL@5WVK9bYVpIUF(? zgjH9FzkG;p7}A19R|=?KDa)^KLVmBK#y|6Jua>>;@S#n&6qPM|TkM#9!oXQdDl){f zrTbxZrJ5n;Nd?f?OgAL#01xdUCsM)#oi-5Xug$?pes}8WsSUMWxY>ZqrTW}qJEwsJ z;RaSaHGGEzk6yhhe+3VTn5p6S0G%K|R;VhJ6{Kws9qBs$wP@0Xje=qjIEbp~d)CX! z#da<0M-VjyJ{9H}(UGBPKWhR5Wu%~FaVjf#+QR#Phccf@DT#c<{kP>aQAVIc$wPF^ zu+kPtOL|G=vHl!q!j{e(8xIw8c;y-OI{BA^qFf~c=8V~J&0Rb`ZJ|T zHWZ+YQ}T9-qM95fv_A})X>g)_1undDj|L+^Q;7>eRSdycYEQg>_ipHnBd_DIy8OW;(*b0Wdr^ zY48Ezt(kU!?f)TcW7un0BObo&HWd$j=5*>SSuI8Zo~2Ca*-F|(2zs{iLQt384Eo8b zJ+4)s1N>{?kZ*7pej4ZVZS4PU<1krS*LdBcQxJtxV2YWu-L|KffHXv6BE&wBCc$^V z@cc61$L*_PX`J@?pMU-l?uc5*G5$si`5-M|=-4%=%6`7f-M(#`T&+f#{Ofv)Nde+~ zXE<8{ZfbV^-Zd(}o4e%aY-kC4bk&tt59i^EBSLNgF{s?1rLX1`iimeQZs#8gAuRfK zqn(s%P{hYnIC~KvQT8pjYiW}XE-E5Nwz7Z+Kp2z^vw$Dv@R1Z~IKmzranpMz3rY(g z)Wi&8hOC9!_Jm*%laJ`g)hh&tMRt}arY5eIGa+OCLA{aZ^88!pM(?Ok6D=9zlY{wECDr* z`hppU4KKTu2XhS|lFssqem-;-(xHHZ3$KsV;A7!8k*kBlh=(U-rxmwKQ4@%!RrbTd zgVJwPe@iz?2-v@4$Bu`$<5zOF3mK@txZ@|)gIo*<-Gb6;jC@OM?9fglv}_p~PrbcU zvK%>AQciQF2(r6+fvVt2pd?c|cP1aFQY0_7%9@p_$p{?LC_v zLdqi>bpctDT0@4a=n;~?D;gAw*Z-5{K zCYGxgLAxD6HhNw+y?*aa1@s($;?#j#fTl#LaEjhqnl$Eu)SuPqKyfYFHaXx}T^OJj zJK6kV83LycB69}j`IGy=^hLHV4FfCABbOmj8L40zP~tHMPfj%i5a6UP8)La#jD*tb zVV~NIPn|qDmeJlp0q>&(6hbDBGCQcy@yBmO#Q#fPVR6+^3jAfw4{#e8S?f0SFMJKL z1Z5f5nORZfdnpb0E;B*!DWV#bUg-7fTa4QN!Hh@-b5B)0#jiXBy$VplQpiB5R|#1Y z)62@KiHK`GRw!gf}asbDA@(*g?Ku@93`N-fg5j~t}^Sbp)rfLV2#)P7$NM0gA}TjqmBByv-lVq z7uHhf+mmKX`X)rkVgt;9{w1lR1SN;6BLyE(arrw?NOM971v}8Ks0T%t#myhsKlE{M zDF2~T(kgl{v2{V`JTAL$pB9nzo(=p|_#m)GrxE+c)4;tepU#zRGNcK11%~5i z-~x4bLMQ)>y5@$`^7ZMjA@!cysT)&0jsG%?v?kZb1ZY611taJ^cykc|KZOE8;?>1F zt86YJ6;AzlkoZJayKh%;4BCeNc*2)qsFZ_JTQj}kl#<@mw}nAnpLsKXe371l_a>K? zW8-|S|Kj!7ElP?e@G|L^^D}QS;Dj9DM=sTBD35uO5FT7o={WH{S)N%u3qfT__CVSv zz88F!s|`6hjHyZK%V2^UYX8)&_JA&LiY-s=&Mf+S_LuM#x#vNo#)w-v&vSeVay!bP2687c)|AOE z_Sqw(8Q%`oS2#NU`%>0TPRSJ61N0ra^Id*LKCA+jy{pU1a=oqGEE!w|k{d>zd6GMYP z>C7*5IA@*SGTv%d*)xTSQ`PSFzZI~tZMCPKDo)PNmfWv#Yn5(xa(sD(d?WZ?uy8YE*Yi?`j3WIw1_7EEqU^i&=Qzl7zu5@cnIys;tPj9eOh%r zDM|m#ER5r75&M&k76eYY<=Cqv@#vII%UY`!_8B^~HCNUpXJkSabkf#VrEcjT71gSs zpy24VkjAZB-}M^VQptUbm)EGJOYSIjGtMn(w02m#^hHhh!AAEUxODH=uL*IsdygKj zta!6e^Uf~3?NYO3?!0-s0|M@ORl9%Z&L$t97GNa){o)Dv6_wEomvZ(JSPK96G#-v^ zRprLP+S=DrQW{YM)~Qn`o(8DL>oJO>p@`4{`tOb>7rI@#H01DxPvgFR`=-{nZ)2$L z{um#n*oV|u{6Non;>3v=S2qsj*=cq4P07>m+*GZ5_bq9D&yW)WFpdnIqI+Um4ocIA z3l~N&UE2Nnf_{98!l)fIG49hsHjh7H*=ksSyKToC&TNwbAsiPh$`f8EJ0N*VElSQZ+U;BV!Bw zrGD4FBhSpz%5odk(REZu^DDzkJ$iin&+Z7DF>|Ilz)l8p-_(vJXc=`o?zSCKni zKeQExZcbq@qX@HGM`Ak;Pqn-djir6;E>jbewuqVh!|*I~veWQa-a(tZMlGJcrPkub zi~WYLUlZH-Xh1;Q^b=(VN7kzV7IEQSxVM@gPt82X`?i&(PkEhW8XmwRpysd#~5E;YkTYJ2ao&KtPt(h z$unneU}AH_>si1+E7j09KY>^beJ=sMd9@z2v#vko=UFBH-LAWReUrQtbXLEu4@jKl z-uLOxgwv_-b}=#Ku2=1n@lIF(!vp=d)>Qxkh%hzy>X%vR|Ld^J`b=8AT1&Wi#^7rx zL|_Z~6MeD=$27^OffuW0K}i+8;hQF65pUVYhntTgOw^CszrW=n*s!|a#l1y&kaZhU zr3Y(>WJ_gcjbm@$EFzWJa6nfzD`eSWoFKkh`GD>@An{uG98fY=L%F;vt~^*XiUGp z=GBvY%AOx}ucUX2&-*-e=1g~7r0mzv+hO3w{yI5By>qv2$D^WJBGYnZdB=8M5U?gZ zG*o~5c%^;gyYN#}=FF)J*0^{@pR8=PoSkYmOO$II+Pk*~>ZHw{o)SMgciwEDor@%K zinWb$vEuhzOV*2ybHHlJ$KpqG84&0!q>IU@)~+2~vwF2!S3PzG1$AAxc(JCd-2IEJtr{OQ`Q&^o+s=Ja~x|-+$){zOC<|L7s7OBT}E= zd;UCN=0vJ_elL&GFgrdy-M8*{uqn-QyY0Y0{#FJ2jgGn!-;p`;Ht**?fgqZoX{UR=nuO zc5Yh7UGK^B7nF}3_TD}^L!A>`8~l9n&ySSyJ$6~@Sz21|`cJY>OG`*fs?Cy9J(4aK zTsQ=VpqYCJ!b=v*uCPIa1~(8j7^N>f{a;IahRHAs8q!<0Zt0R?sPSshREFJEwd4CG zf>S^5z}?{$7DqRLsQPjPVc3LDn;UD^7u&!LxIpUY+7QXZFwDyS{EbTKw6}ZfbEi(J z177J;@et`aqkfu;lxS8;a67UwY4`4ghlj@+wK#tJaZ(jpx*|O%eeet@vxJpp~i9pnG{)fJwz}JNC{a%DpFVxM8<0o$ z=1QHrbO}6lN{Q`$vkAx2!>CtK zPqQ6<^TWp&7$^e&+Q5x0?XTKv?)f_Oe@1xtJ^VRo=-T2A$f3O1Q3*G1DzYiIY}umV zo#eJ-$3*Y)l_Vd)9yQ;)fiu+kAy;CVzPgWIua*{It!~A=Zs{&xv0{{^r8<=!n~X7P zuD__iczD$Zhd7H1hZyJSTP>bJ@oSlxs)XW18pmR;zWK7&*&=g9v%kmqif!KgwwKWi zZrQ%wjng12%b1{zNy|Jsh6sx!Kv5e7fYTde+Hb7c&O6C|4#(faAB^JAVB6~OIwNgt zY`mK_n&>|%I1zfFBy)Lq4qjN@d-om?Vr`T-RbRgbo52%p5^-IXnX#pomYafuyTMI2 zR#vXV*)=>o%)fBjxDnt7$3L5IoWT?erSv~1PN;FRU_2kZv-8v0sLc=fnf1zAywJ_{ z^MfP){wkp0euGZ0$jmIT(u-1@0`o`?8&M_CSJdOoq{lsohqxoZQCZwo)%%PyHi^z4_Vcj{&N#gX;#}#A793K zQ##*Ts7cXsjEsWJ%Wa0byL|tPjzOW6H~b#MF-ekdc^2>T^9u{>tzP}Po$vHnv&hA+ z&~Xg`)Q7QMUgmC$e(_)HH!@q?=mo*9GPwPfdKPTI1iP?v zS8weibgxr}mhX1(xisW{<$y~ zyk%5J6scy6NIloc#U?+|wDMCc%Ex}Da_Z{NF6`5@XFb}Y!FKtL(MXj5qjV%WLTRY( z@1)~#>ic)c#fGcN(#iMkQD{j>MSnZ8eQI)9xx=DGT{tW}ldDyg>z7`bODiBnZm*V! z&!2DHrQY@CKco#%Sr)=XLxS6@R4?oWS zdy;~VasENDl9+9;t*{mxBod%Q)ileEI%P#xR0Cc$9$cyf=0EY?y&Z*Tr5rM6DybbK zr`uV3qd9YIP3|8BhVLW~o@lq)MCqHUy}f<%KZ9ucgL=-<)l~@C-g<%dnoq~?JGlk3 zm#Bcv^;}rF8Va-yq=!kCngtG9$!1%;y*o1xSecGFJca$Y3w`JYZuKB z)UbGwD!S<|L{=>tGC{);)wrAsW-r* z>4riIJG*kQX&Bo8^_bS8hIYruWwkI-Q%=rRzeUcf%H+~}hgnvy!jMRxlxJ209tpL53(ZNZ5;@2#j*BI-Jgt-GS zo~KE6BLzl_w?m(2v%uHL$d@!c6_kfN_UBhKbY8-ctaOEid+MmHqJyf@&bxLyZ_jPp zl)irbnhj#b_I`W1>+uyk#Q2n+M1cxr?HixjX6ELuRQSiEqm?N=)}pWKQ9Qo+{ox!u+M~-+040U+LGaxee<$}5h+zBQXjGsK&)7!fdQoLex%hz7K zXveTeTcA(rZOCa;vc2sr`9y0Gn(hh+*g^M|gL~mMUQ0$IGP1HPm_eb|&WkbpyX6<^ z&X_&hBIlYr8LgJwO@RTM8BJdEuZ3N-w6t(FQX4d=mE1Tgc@EV;4&b}7uR$HPgd(n|`h;$Ehu zYik6bd*e`EarJRpNnzXe$73^}K7PDrNWkz}E05f@nM(dZhnsJwjp@ni1EyMc9=t>* zzRTagE}@jAV)L!Yh^Pj>%zH6Bbmhu$e1{)cXEEz_oqc#oV@KmzByFC;z0FrdgPVM0 z#1W3GC!Pq!+&Pg=t@RZvvSRK%F(Z~Adi;sG{9OJo1tb)&J_rap|5_NnOe#8t=R zY)$q&?CTXj;Adg4XX#JN>zfv?7-HgHsQtpz%49{sfM;Pv<(W<|rcZ1e_wwng@1KTw z>?MkF_E8?@Kx*2oUY&cs-SPSr)pUQ?;wZvz+xJ+wg_+pSl;*G#%a)8b9M2a4Y0Ryy z&&S$a+fDDhfMX~#$EQ`s#OB(Ly`%!$h(b=F()i?%J#_8Le zR$&t~RRiq93YFIs7A*Jp;c(exiTUNL1@B87vzB?^`@A+I#^W4mZOe@XPT63X8(Ra!!%u=|iuh9ow~U-)3Z&HYQCKlq!ZF9klFerJwn| zva1`{d3|`h(&562?|}oX0?w?QJ|{T9DttwhspeWm%dBG+t=~<4ZWU~7UE{gc@$w-v>+pX4q+XIyYI~G~08<8hx)C<`0qV4G#&`iBCPK`YpjPih!lvnY6VqAIy;6JW!97LRxmH<0 z=fXoWUF-j>Ri~4@nX<3zlcIxvr zmR_zST%s2J`)KQ*_8h)HzRa&?+jAXg8QL({)N#Oo77$r)VwxY9l);crbx@C2Jl?JJ zLy_%esf6IbpZ zl(DpGVCk3h0jn-GD9y7-jWYaqU%to>x2QY3x983|)K4l6#Y79^LDdD3Ujuz_q+PmI zxxtvjPJ5G`o|-&_b{BzI#7u&znElT|6&|_z~D)mMWaD@%d3mefoy3ygEujUYEQ`z=M~N!Yj99`Z{XSCk4AP% z)i2!aS3PsmU-0!;L*DpNd-*|(#@h`^VI&kOGZ?FPmfzb zeL0x0100b4#%`OQbB&|tny;Ar^5fS5QFrsbJ3GxzxcOo3<~1`{&h9;GXxGg{e`u>H zTTL$*Zec(EDXYM`b$;R16N9`{Tm9EAe{KHd&9hOHlWJtNY5ne=tuou`x{=tCd?ofqB9-)< z|0J3;ONx56u>Kl%t}J3jRFlN^J1QcttTA3QIcpx@^y6~O+*z~voQ2Uk zL!H8ltQ5+^t(L5uyR^#S`>EKX$46tWvdznSKexJD5&5$4-sk*@SN`kcChD8spBPd1 z=a)BwO`Y4-=uALTyh}*$$HeQ`@85Mw&pNKQzL$~Wdf?ze3pmWLB=w`|g+CVgFEpb# zQzNJWr0g2od8xJa+nCPRc857tzBA5te*ZGAJ*oW$Y( z$4*&gKN?LR_xondiJ>rQPUdA0vi0 zPAbbbn_O6E9@RE8u7N4RX+`ChMX_PAv9H47oL)NEJ7@0ycZ)u1{X8JnZ1s_yj_ZFO zkNucxTbCugIVm(v;A{?m+lbZMf;Kedo{I|thOlOeKO=7?;(Oi|71wTm|E*A?BZE_I zO`571yg{Lh`CKz5R^0JR-CDTHaa7=lW@!WcSJq#-C2P&`60=A9FNYtY}!jEYI;()1sG#vsZ>U|5!9|x#f>W|Me~r-9sJF$b zJl*!pXj09&82mi21>Kk$a2=X4ql?yUYgN_xX3Bi}4XiueP@Uw&RTjoYYk0O$s)&3r zu>OF3lN`%uM~7PUG}nxFRJu^Qc=*9AS{0Htgz?=jrR$ zAH4rT|Hs9gtwn1xv)+`J>0J4?@nx#!vUy$q=FYLsh4*Z8!%EA(j&U}Lo+P%X(+@|dM;Z5BRSj;m!&$@BcY@+1BBr#>#6TtdM{;5g=@h>EXgJ+}&0uB4 z0{gyS(#x5(l428$>kcs$Hug>J*(q8hKEtl8>xJAtw?9~?mhG@!5@$TrDX!>XVc6Al z+spHl2Bi+aGUVe|+a(vx&%OU}^QZmkgI3+Wn&wsnpR+MYO1~Ie)F|KS;79fN%;y6i zrRD{^yO+`-tLRK4Scv1 zbo`sH3o!Q4^XHrM`A?oa$v{o{6mT^JbhO@K6KX%Wn5*1q_2o;!KT;zl90a{$^j_X9 zDEW8$ON~|^zGjr-8pemL?y3OIeiNy#;(Ob%Rj5kz09Uylu?~s%GMB!S%f_$N->%{+SPikh3|YB7*8^-g)Ov`nCS^#yvU$M$iyV zszSqe^w_aY-=a^St`B5!GAztvQtQI0xdS?mQ1_kBX|A z0+Nj8-?jRQ-RsnO^R_ejDX@8hlrv0mmulsK0|MtlY-Dibv><~SB{`~tj%eCu$S=RqR?fqC3)I}cwV=XiR5E%R? zcka^DoUiwh0n5bOx3|{)IMJ_fHD>c8E?!LHwnj56t9#$qG33^#QN>(|PXAOfzu18$ z4}jTEYe_>f`~bYMG1>nxphjB+sM73>C$7i=j=S=A870;gs2j@MVY0@_C zMSA+t*aJfgz8batxJ3PVB`%u+lav3TA}!Ds8~Z+9()@cTw>ufm(YGJyXSGr3b^grm zz)k--sm38^&Wv8SZb+(mO5<$i=@-Qm;~}eM8Xgj|&P)aP@H*-#PGw!zKL3m3`Sa(G zUcK55vcAZAC~hQ!hYr;;ACAmz@ZiCH+h=8EB|d!E1l@Lp&LeMmK0$)E+@i1Kt`1MI zt;^g8_7xXKrPZrfPb$>hZ}AP)h8_r0g;x> zWY85#9W7_M)Y0=M!lgWp5f0T$f%TeD&E3sla1rP>2}36Ks9 zKu?$6r9pI9Os0LyHt%~BrVk@12ck@pbnmVT~dVlBcU3%U6IDdgPn&B2^ z>|6T4OS5#z;>8|lQlVdK)~e-i*K_oO%YSJ0&Ye5Ms2wO=RmZ%ynp!nhVH4oss#px+MK`}H)^q$iYnWKKaB~$pBM|B3cYtp!{Qdv^k{As&-r_rgoosV zgS=JB*F!V>#wrv|X3lIO(McpAnB%Q7QB^w)#?ubqpR0T70-;3U3j;LN;O?O2uSXEbZJ1dE zyU2zB15!RQ{P8Hf<3!DfyP7ci#4DrJ>lg$_KOwiZx%yxh@wj41l1F zKv(mNf|BjMOD&jg8!W$jpFU$C*L>TzuI|L=N#1xbIk~U-wasg)z{UD77hcqTEHWCt=9pOtm6@R5{3)c}q3*Q^;xeOUu=aswj1wdf9_ zHI_dxzPdq$SPDlX(t`+4F(QAB_~hjJazY9U3)Px#-F4uA5=Ou9acg2!FAi1q&Wbu{ zHajpeAuKeUlCTkgB+^JQ#dv|4_k79C8O4n6i*yw(z`UhmI=Rus@)x({U13BUw8NQ zZ3UOtL`7vQ!+nPeHE%1VF6|F5y=Cjxk#py&a=JVCj4xqmUbHvpgbzJt`o|6QpJ_Q= z#5Eee7HAwJ&Y!;yK7srQJh&e)(4>M+Hwy&@-sHsCZYSou0QDnbm5bL7Q@tpf0y&6R zxP!w5K^1^izqa3EluC)>7h}WO9Bg1TPS?B=Kr%H1Ddi(oS0Lqzii$GD*w_nH4ydq` zmR2*?E%_|GQueD?)uBAsu3v9~Yfe#2sU$=~dnW_sH_Nt-6w7{LoRC`x&V2FWp!wW+ zDIh=Ohq3PxO{7arTD9^d`ZdE9;VTwvjRGclBESIbn3hj!7#kOP?wmfvH~mAM%!+S>c9rJJT(bEJe-8w5_B3Kh|O(HW_h<8 zxaEoO4~I6sS?$dSN8L5kvW~v^#m-^<^t#_wlsAQ|io}iIK)d}OlUv`=5>TwDRFkzfu5izLy+`4@`fl`1K^gt&LpL+eD zF~b^HS70_o87q&iJZ5y4LePArP7rE08!6Z*&|EOl(X(qdQv34d3pBg13ICEbwip_T z03~WC7}0)2)lV&OMnb~1Lm80~5iW!TfCV^--63dRI2QI6W}!T;YPcL>Y8o{a&6O)wT&L0VcCPyI@+(8xo488A^PFPyg*Irj zau{HSZ?B`IqzCyd=0ah29Xl*sV)pew-~^Mbe&vu1frt}K3Fd135?3Hne=0BTu9 zyC^}>FKlOI43N0dt;$erV?LUwjsS8qgKs#_ZHfu? z@9=-*Z*%MxhQU9vmRl+PIzaTy%rAx#7(0IaCd01!3l?;=T)w;?W`hXpNJz)m?$uSC z1PO{nL+zIyL#i%7e0|=$y3aLaBx$wUkcW`dti^P+7&8nDrY?uS@GPv*`csD48IXWz zG${TNK#rtEWOzby5W-$2&;n6_@d`@`pAM$_E>djOEwwL;+_9qpy$Z0FH@>#duB>kb zsmt8E-pG;FAVp!TZ}dus`40;VGxXHacL^^_KRNVewg?Xyfs-q-@HggGGaZ*v9dlxO z9bb(RmdJF7XiNvdxFesEVsC%1In^VL>Jtmbj7ie)eF%yV$=?ZKD$|AF5!XBDNMoZv za{l~woNsAtUZIk>&W?%J2zklGbTfF&B!WUQd8J{-x>XCF@eG?ZZ@!tR%PLvGj?e?y zRXZ1WEHvHcUZIs?;i%wLHDoeeG%y@xhR6H0me9&oppeC!gSK)e$pTGORh4*WBs=bY zID0CW^%wn4_vX=SOFA+$0vummM?gPat3{qCNextiC@cSHZP(&kKp~^nxK8o)W|Jf4 zPMSEe0S6s1pP=*TRFV%2*j~4p@-HQi-;*P=LPxJ!rAdcQUVQNEnHTIR%1YL`(YLZ! zL5AV!ojP@@L8&3kPJh*jvBg1=KPPQxTY>=C(gRWjcIe-~IjKFnWbNr|TWGchJN+CC z5sj7%rG-d1*;G&x$vmsZhij=UrO7}c<*pa#GX8`fyfutZ!s)!16(1Z<@26F0i|9v` znv`PH`8iw*mVl&m{pGlRMSo?N`lk4!%WjxE7k_|`+6Z*1OsOZ?75W{j_Fn2SJhQ%*E@Qq7waH1N7%#4Q+EJ0q5 z%CDLNXS+%J_KgSL)X5Pb4U!2j=d>TlVWr z7&7r>>lkZ{A>knJl>TVzsOo`J>I@wk+s-!-9AfwG1Una|W!zBXq*k+r$9>%O#pcHd zl_6XZ`if9FG}H~&7^yQgcFb^_7f+ae@;_=y@%pNb3FBExPQm8bkkx~X)C z63Fpm3Hot3Q2$8a&?ABRrW-d7Up*qRyK%Q}-RPX9ppv~}W8)GU+EXg+_wVa>>lR!) zDE)DIx>mrq`T^h3IwjWp$^6WN$B%1fkH~%V2W268#Xo=EmO+gooh6^!1t^FA|J1C- zyw{myYU<5=7<916@Q*(815gcJB2b(<%WCXo6QGW zgy!Zy+ZpYo6OguKylWiyYBs@Ax)yO@wfTc7i~0w~MIoR7za`Y{V(mf8IM|*lFMmLe zo;}5;Xo!UrJ5f3~;sVs8zrs;gDYW0J%|m~eYK9N`px36EtkbBG=h)6TF4QsbZgFH?p4tGUvXO@&`m-zDKkxet* z-Xj&!M+YLZ#)Aj9lkQ|R0g0N3w9?;vnG14`#s+-4+2!)`a!&-|M!go>-!JfQ!hsqZq+tRGl=!2d@%>LA*Bzlg(u z^-Lj#*)3dtb<-}N*2`^Du*HW#*ztEgpZEIpb-UNAZEcsOhmb}CQ!O6wun292TT&Xo zUf%js=;_l7tyfYAQu(96Y{KR;+?Dd+QVN0R_0Zdm*AT7oyxn&B@~{<|=j+mjdWyni zQG;kE1g_t>A=3{o2FDW^u!@9woji^#Z;3W18&V!H9P@ujA0CH*x)SNiq6{DF*0I)Alm<8u+wAJP0JxNy274gjZn(>wSG2OG}s+?lXdsm7auH*W7R};v``a! zCPfSdjG|Vk@WUVsg&N)-Zbei+jL?cMPRn`;v9My5t4GMcskG7L@N_M;t7K84t!Q<4 zUX*L*IxAbBuAx9}w8p~T#Mn6d_3Khy&#Q+w8L+je=%P3N82I@k`bTa6ZOI0pK2)I1 zP*Co-U{tKeMh{)ntX(f{>ex3aqlcjDF_plh;DSaumzx1U@47PO6N4IH9N z!3H@UTxoZLtW2@L>+Tz=co?C8b!MgNL>hUK$32xw)6&x|7}W6_w6dKjn>Kj<8n!vb zWPlJ=j8Fcm7?9Tawu@bF+nefz$1X4-TPHb2rJ0HooN6r!c$7#Y0kONfQ`wz4g;oel zuS318gnIBOT%~ve1-+eiTY#mVl+1lyhf;Ix9(!HeX35%SK~uUjrzGAIB5|kuL5V!9 zT_b+^qM1KPBvSD6^?#MQHT41;qk=bh=wUY)aqbvBz3K##|A=#y_&Pa~TZn6hzL7kI ziuivF)c6l7Ak!}TlC)24E$lzlL`uy@U7FT~CLCavJEg}yvrNNv75483=e>C&I_tef zgO{uz*fJ^U!K`Rd;;|X(qv=#RRvsHXxsl00M6RSlDhY@HI&(#>tG-3bKGZ*&x$_xW zt4HWsqjv7FcGMnE-@SVi?aa|dZlXAEb`4izi!VW8Xjf34A|`a3duDM|ZT$z~7cJ~F z`Z9O>y8(DTQlKZ!GEkU^*C>lYX)e|)^PyZr&vVI}5f!pt&fB+&9FS;gEN(oIyh-Io z8Ns-gV_NTUutSFr&z7|+(5m@^B8?igzCuJ)ln1$;DfWJdR=Q>^sq+OK!(qsQeY-yV zKhEQ@nhgol)Ye$@HAY3RyekPq)I}QOFEe`~;=4oZnK=GvUtC6g`!)Z#w+)UA^ng@h zi*yU102lnM%yX`+9e$-uRpvWZ##KD&-skO7#2Lao? za;(_oiBWZeMRg?=9fp-EVkaMVSEavO%kRqzsqziWFGRTxB{1n6Nzt}(;C2xzd$f-N zcs+a8hQ0(CfDYKk!C}dTLnx;f55cNx^Q=&5ueB7{G68C`8PMFpO%#N0|MF-D97sfm$X8?c2qbZq4W`*mH9 zld#!8SW%1}H_nxwN=7O=b)sz2Hp?-$2&NKaHpqCimGbe9pk6JvixzHHz;oI=a5#V4 zvxE{pRPx|Cty=k#CKL5%&1#uyRg!M%>`vv*s}Tn2)2><08))aW@Ag8vRXqxSJS`hh z@rBIL&URkjz~}FN(+`*xYSrom_eC$%{-UB?$_zK}aOWj&urknDLB5z!M-JStD)!Q) z1Tbj!+Qxzm?q#^LW~5GHlJIayNdepx6hP}18WcG?Ixb)!1+{)@JD>XJiL{q71wn5q zwWBPhQ0Ikbzn=yg=K|Vz?&8?l?eN;_*b}Hcp0tiQnQR+O4y&QC`q{Y7O~3p|DTUvH z0;>o11qRo8W2^3h@i~BCLZ-E$c^T|j+8wj#MEh}G2M(wTO)~yOQ}Hn@W~wOlW5;Wm zP)hX)U!u9!^j~pn&Ec*$i?AK|)raGv*D!Xw)!@1n7t%~!hwd;)4V!K(kBnEW8J7_y zmSv-n*8e-_vsKjh9UAL0%GYj!VY`LOdqaPL6}AKxhLqHX4QoSSLS|oR+sh*XM-Km@ zuJp*TcN81Dtu6*vDzz(X^=rRGRWg3b00;PpCx$J#oCjgX7~>P2Wx&x&MR1=9k0N9xus%JbUikJ3pUWFJ64p>+yh^erpOIK(+_z*DM32OvWg?n>?i|piT;k0V}TU| z-Yb%Mp())3)eafGtdS5jX2ZAzyXwi zXAAm2K9Z2=DwAOY_obU=^*sn80LOx^zelo1)%)4tPfc34-VRf!nRAQrd4R6!T(OiL zGitBwP>LSjBr?#1Cr|dPv~B&nVfzy81@E+hJFo<#_x2tm7{k2-H|+Ku#Hy&nux6>L zj~{QQ_15g<$K`aztbkT{7W3e9dUJQ1cino2|5HfOAa2&n(GT!iudKhW>W^?PosEtc zpWp?8s5Wn&4YyOI{RL;iV<911FL_Iv%v|2O05a4<`wK3UWtNYvm+<6BU^c{c(4)_; zJ2%ogC0i906=k`9&s6+De>-@^(6VN!rT9vk1HTK8MhPe*h{xMK3{EdBxi{!#cDQpz zPcr+9wYd#0W1O22>(EEULR?`Wy|S_IR+2lm3Ytlic~hQ%?=-m8fvTKOj#GpTXY@Uu z>8uxTtl(S()kD4f<(n-Xpv{Ef)L)Yl$j8!8^ljN^z88_dfumL%&GQu1N*i?Ai_TN* z&I?+OQ)DvuIs<@me{&99)~lE{lay!Xho7lbdZrRnr-#pYb^&I0wIEk(GyC&jb4zkr zNl?#cOt1Ch&fB2aHb+u|&627x%Fu;3NVSg)40Ki5+q3CbBk$X1LPAD@Ptj-qV&Pyk zJo(U&X1}W?xF(A)caOzw@^o|6s~cn$eL4;m9KRLLt*^!MZyR(t8ld?DS2WzTWYHqE zfdluexc&UkP{px+w<@x!U=7#47rG6(E62~TID?vSy|Dq{=cFS#4SvsyQXMlYBK#F? zH1oI#5g%U6n?2j}PuccAs)-l_;_77K8h~t$8&QhEwR`tlC~$VQGo@NRLpu7efE0>k}OC_$c$IO zat{i>7+qf5uUQ#Zbef@WN@o|_M5yT1?K$goHoDx}h|Q|Gn72@W_}?6#U!w zDH=|n-b~sS7D*(DAi6k0JfH7Aq1`09boMHLIn33N-5}CgYml}%r*I|SFPFvWh0m;DbOzOb8)d*b*DyI0pVJJu7)Q+(!ocs z``q>OI#6xGkwQF-1sT+jC&9IPO3dQCT^(a~uzqds$gGK63G+5VE@Ath#W}a<0yZ6; z%C8pv2Mk~btKO>{iI6vk9-k&$YGwIEVG|0Pk&8)tZ;i%Ho!Ufr8kyD~H7erp(Fc2F z&UMKWVI-Lcw;Q%cC{BYsnFsdrx{mUECur(wlZGnCSY8l+L8oUQCz zM$e13QA@41)2g05e3nQcevdO#iZae@epBI`RVz~@Mhq{?g?%&%PJY3QKe63C@wI?i zeKPxfCHG?hU1IkqT4ypM@r06gEo}9i-g)4fOsuu%PQR1{eGSwjG6|9FI(~s8)(6F~ zytXEa-Dqh9_J4(H@AS}P7&MX$IN(m42-1IX zNs0N*2b26Y-P2ad*%ApPBS?v#94-=p#J!^B_BjDxAHB01%=mih#(uxmR0v-AyOx2_ z9YM>jmw==G;)gwsQzUl1o<7I#Bhj8AmL=9zEJRejVqP-=91$Uw;e(YO`V@1V-t~X% z!0b7mB*$p7ndY;xwKc!CLDrvf)gVLv>e$s(8{Tf@mPmA>GA<=L0QA~lU2{K!h<|0) zC~L=s524I`QM@vGoD;YoPgHlNY|M}fG&0#6$>AF8Tse%sQxPnTmO36y2sIq1%f;I} z<>+RO#B0~g5CgIrBH^r2x%L;bs>ppt17xBe#;-O2R9;LQ&FhT+H-WSfc?Igp1&{N( z)pi@_QJJY(^TT7y0lx>;rGRCK83^gzc>93^2FN51$bk&3sH@93W~%vp;JwVuvb}%n zkX9d`U8?av>JV+0lj(&*x^~TX_)p zCE?-HzFgGXRbepy44cq@nGhiBK6M7Mp~WZANqGUC(upk04()f~zQS-+`@dRb6-#QS zc6EyF+r-YBK0Wc76Xb!ROSqMTj=tYYYA#TV$1dq6Q>P|)y(k*IExqpxF0!c3k_LEu zXES=dai6!j^!3ZC%0UPowtze2LY}tYwez4Aq;^j1$E*5wcBL*l_os+hPoRG=m_&pw z*>v1nM{PonS?$V}Pux;I6c0dw+i+KIcuT^x+Ge{qjGEuT0CUS^oo_X+Vl~Vk&%H?(_db@yY2~--^IWf z#=L0l)(&fDG9YsT6)-nWdr;0fC{q~_ZfLG-l!M&wd(!zb;disRgI`jS~haQwuL>$ z2X5>WQm2Rd+_8ZRHb?I0r(9UyUnMs&X}zC$@`lYNH#_{$JnQ9k+UL=HyYc&vb^PbS zu`fT8erm_54t=Mcmg^K7FfVv@*!^{fVlwZqGfrtme#a?OM#UF!a~!TA%bpw$csYxB zN8ERn?uRO3?f23i_>6Wwl5{g>Mg0lR#K2LH{X~U?u27my(6BChzgzZ6_)(mrf4dBL zw@>r0{AU(jsNzPA&&c9ohh6H=jT^}Z=u&&O_Ta%AO3%K%i&!a# z;vL%;cVdroWz!~2re665{}PGM$ch)2Rk+lwsdmEwtC;M|PY-WjT3Sklzg2OFO=Q2N z(@w-Wb9LeF<_h72F>;uoHs3Kf*JO8pE^3J<_1OL>v!b2I;o~4~+;>PO($AjNRH)jQYq>wO zqI}=g19xAR4dIHVpWjx4%RuIL8a})&Q_e7&LMpTy;Z$E?Dc1S*rhm75k^bO8wrlLD z_9xMMP#x(_nbMe7_GCt?f5yfM6W*=7v8{zsj9m{nx7N@5$C5OKd0|v=6f^|WO0@y( zQAxz#zWwgFM(})kf-H*9>ciF+D*zzl^RRN)k1icM9(!w!m`CK}qElg7zD`?D)euBE zrA1ldsU(ab&Y7Ecb{=rR?p=5kmg#6&$0{wwtt=mN{(oGa0Pb9j37}4DGs3BjsQ!t^ z?v%Y~AxGV=^O1;v4C_81(u|qF~OgyEL--VhBcHT_Rdrc~p-?%2M4%<&lh%UI51gX6!S zICyXyPn)2j$Lj;Vh0x%IThb}=Rx|P0#-G}J=FHY0K$%%tp1!_KaMZo5Gy0*DNJGPrYEx`0fQlpMg**F>`f;hnE*mkmiJM$Ln;?ER1j4_Gi4aJ&EX}OPBaS zi~0Bb<4NoS3;87s=P36u`tq=M#WE)+3*HgliOs%c)qGy>6!wL-czjqT|M`mC&Z@7) zi;GH19u0Zu|J|;(lat-Pjw1y81wH==-p0Uhd{X~$(~2X`UdMw7kbe(Z>@{I+>C?+y zq!LDp$N2_(1PIWC>CE#Aq!J7gJ2LX>c++r}ya z7|w=CfGGc*>IR13))ilqZUq1;3rQ&kDrIyxo}O*;%*Z(sa^dp7=l>sGC-u9dR;Cp7b2e*Tmt z#d9gcu;-kSIJP{PZ$9qMCX)%D9>va|GpCUPugh(r|G=6y(ACw&kz&;B+3f&k>W!$U z??%1f0zB^&&J%vGTbekt?lpyDA=7En0TG&Il3Ij>fV*%Xo);y8Ux03*a*9Oig!jZ4umb4Y&#V@sHs}s>$P(Wyrk=_V#*A6&MY9X#M{DtnD!X4T?^k zJ8y%>&Nce<&`g#UJIz$!j+jPW3D$Pi^zNs(Z{8>rY#sN+a^=yiT``VZPexmJGzg9n z{F=QO?Zd*tL??v0tKq$z0K*^NUS3Fb8|xn!SJdr`Aytn&KMox4&yy{$63sqop)C`(QXfvN?d%OQX@5BTGfpihM6SlQ?^t17E~OEhsMQHGFe*3kro~ zaE;Z!qF`pGHc=4WjwNuT9_l4m>$6kv5}_o@2RcuY9|eGlc6r$WSJ7=dcBsKYo&L~m zDR0W@hFvv^)O) zWdD8-o`(qHiHOVndJJK`Q~_z@NrL+bKFF!iP%mnmTbweY+Tjw7OVWoG9+^+IF7pP5 zvt_EvCr@XBdl`AN9yc&Wt`Xf87~?cz)p!m!_nPP71(NXQP2dlwY$A+-;&83}$+jmk zRX)Et?Lv_AF2`3(Q*uxObZ9$7K7DPH#bfL?+Y ziiw7bViP9g^}4E1oGN2QBOaUn&o37`1;qw;56Jc6k;C7isZ|vGPrqfG`wU%MlsPhg zZ23y3JDX7vtj&wR@bAp;&cO5yCQY(zeD=nTw$hP`KgR;>A?*HM6_k0PWU2M(5&0)I zqV73^(>NN6`GdIIp%Ovhu~yR~yP^s+d!-!O-+$iqi6ED`4_E8%@E3`(jB81*29Sg#qUy@B zJ|+{!)jdZJi2UBD>W7u`82l{#Bn#+d^`P=eSo8Z!vYbIqHIb)F7c273ReH`PGOZ%|BkhEdCx(lp^(W1(euKZ26Z;kqB!19nTQEMq2^{LjB~0cYP4wlsqUhJ)GWf_&RK@s9_&?5ZtNsw=&{$^{VrL2X}dH$@F;S zH`+G(Lgn)xo0{EGM`wH--6o|%0To8k%Y+2ZlNqf;n;Dnp?1cZ+()E^a9k`Qmin!?9 zBL@!X8AY?AO%o>^ONv-yY_m79e@&ip^wq0kfH&lN*k@Y@_${D`694b=ZOJMMsot!u zt;KZ)Xq5nTS-z!68z}X}C4}yAB-T+yQ(>_Z#Ym<@k4x+Z~ZW^c~P$+<;k7{zAv zIdN{&`>A{sHyMmwFbmRRU3d(0=$6D`vMz`z&f zjRR6Yu`n`S_g^>H+&{C~mBwex2Mg@hv*)JLYj9n-TfQD(F1O3iw5E?AA?^g>lq07H zc13OECZ!zVDQKZK$N7MNcP8|?equuOt2x96UzDa2#uVRRj|@f&#hX#ZKEoh1IrTRC_T0}?brn2Tu?#$RTL=k zQIUT$cP1HtKt!VG$0CwU^J2MgKJ)gSri$=$qrs(-wMg$I4?_Rkpa&;M93jo*J;JKF zTv7Ac!j-+9r$R#NOXNH@uraphTQ6N&d8OM|6%k^B#n0>ZjZ&Z~3E(?}Ao+!b4G}3b zVoU9OtYKSyKPxdk#Lh?@59HgZMGZb;4WfAAP^>5-1PkP9Wwo|KaUBQjVcz#Uu(etP^G} zahN|bLwwV?^XPs(;TPC^(U3gE)?-bq6pJ37Z%xN^>|x4hZsIFAA=IV&ThtIxY&gC| z+%|36$QT+Z|G^eD>?G;qxY+^g8A$txe?c<7Q_Z+c)V3ZVZrid3GxWa;`Nt$FMIf~&y zQ!M1$I$ipC0Ra*{seJyB(8@pKFA9o9HRKRwH}wPQNkCkbpsI?ZCsCbU*RJg{?YooV zS9X^)$BDniH=O~obarCB3fJ$qb^e$!s(j#6%wq7;=s) zHZ_Ggehs`M?MCK-qF%oSv#CvQ@v@kb?&WH5mR&i3eaMnyp%QtvXsn@oCW{IFTT;IwfCdDTfpl~{ zNhHu9uw?{0m?I^L|5o^yFxph8%dFYX-{Gu)cj_^4P?U4#!PrSmG+SCuY$@o6fvmXP z4x05dxbVHj!wm9-hin!0mAwkW*^2U?YfmCMMd(B^z~H6Tt}TL3rnml=zQ-WvyOZV? zv~==gOeZa1_7?%O> zli;~$&z?*jWo!x85X_X+gRpCUz`vFGN%a-x6xv-D$J1hs0)r?=RT`YQ&wM?1Q>L8g zXpj5Nr*vUv^wgO%VxuY|CcZ>p6O&XHY3j>KRQ&@r3wI}p?+3KIm3NzYz^4Hd&oUPw zCO~j?a?RN2Bg3(%l#-aIz&D!95Rz##Le@-4UB(l0FI`7qOXfq8&oze(i4UD1uV?M2 zK9=0JU{zoSc|X0ikS1GJ9H7r037~6Y(h@Q1!4}_%d&*npcXo4HTAEa(+_j+d=XcZp zjf9b{Q4bwOt%pcuH4qxIgHB9lkqFi!|Keh)uo9ReNbol18|V2rt@|G>Kwo2HPx`LR zsGU9yu24n_B0z_hg2LI8n69b2bKE&81b+q$>G!mews6T7GB$?4_dr0n{P*v7(;5zX zx=j^+m_<-E&zwc>Nm;~6e@(qlzHmC_DqlFaO{B8l$W6rcRDq6%X_22bS@`(%HQ%B_ zpLA`tTe@O&Ioy_Dx*r0G*NGDy$kBZfX$VR}Kg+?Abf5X@^dw@6sEd#X(pYz*$zaow zL~%~1DiKO#=5OD=1?JcaQ` zN{gs6F!aCwEbE{+g@H|GPLA{@KvL?`yS8a#PLs>&s(0qdBowAe7?79v*9d@5QV0kL zNJOB;{Sj(}-|}~KdzuZg1!UI8?uuh$WoroZ2TZ7XnS%1a=P^wwPk>dmO(%ssq86cV zRYfQ_lIbE^Ft1+*4k!djgK0oG^zb=74g1~YMc=+%bWzh?($%x8J!DExC<1d+`8Lhk zo;ciZ6j6*x#+faS7^d zQ@XnEoB5KxLWU{sF+xPDac~M0ye95$FI1@Jj zF&Kgdl?~-y z#fKN|B-mh&Er>j4vh8Uo!(>ovep-Nfu9cT>Mb=JB{r{d_)xw#`V(fwLd|YK@F%FDH zZ-C6MqiC+^$QLYME=>dR8c(IsMeC>bfoMWiN4t~?gp+k{dXJ#alE1SyzJ5hsFt|#! z)v4LeZ(BRazqRQ+qyP1YuzzQMhPG}AS}gSo9Cf3{jg8qLDz=DHJaP$@+|A2wAOs=| zXVOJ1utt4NYicG`DJ7K&1 z&sbUmGc5>p)F1CANniVo9oq5-cyXA<9$$QIrue!`u3+P@P!N>6AinbADpQmh{GwpH zz^j(*_{p?UriG%$%&D@z ztl#=HIEBxkkUL=3sY_y(aW(G~IK~{99R3JWb(&%&_9imsk1uvK6pBIRac^ zETl<;NqOIpSyk8=L-Mn zC*~RQK8l=`NYhjtU>cJme|;IJYpgLM-al-8_$_8O4HS@cls4LkTSW@Q38YF&T-K@V zY;0_MrsdXZZsB1tEd*>MGXV6e4HyEG`X5@Q=(eThz59IHzUb+heUi0R2-#YgHXDB( z1Xr*<@fhE)H_FR5=M6#>dzu+B)uG0YRSfuc*gRfdT&@COdOHZdAR^opfITGR$-HKT0wABB z^S~SLsT@6UgJ2N;dR<-qg+%ax=HO4$9M$9Y%B(W|Ikm3zh19}om<|f0W7=EC=1L4Z zysVF#wgk{*5Pj=k?dLlL4I;KE$Vdd{}w-|PLy>}m5Ut&}lK?zKHLsu*KsS^AeIb*m57wqB0XqKC|fAS{iF8#%epn$ zC(ZfOuw4yMCW;Y?Ai5yiub4m~-LYz*HIU>s;##InyVKIt0pnAXy?Yrc@2atn@{(CW z>nLakOl0k$4D2ZroL~(T?dUByA-Mkg@VNmK@<}`EVSA-~B%*_INtFS#K{+KLPL;*n z;Tvkc857(M4%YCWAGxHwPQ<~jU~H++o6>Rp-M$}Lg^{=vQR`FYEZ}3-%s-L$9I>0X zulct#UcYH;dr(F}ui2Aef%Ln=TB%XZ$&L+LIvR!MrcNRFr)aXmbI?lB4B^8gzXz0l z3{`8}PP!7|bAEzjr-_2D?;kaGeijYWXA`%ZnKwwKDhm~U=;7``z3!byzsC0&jKvlr zUa6YM+`nI2VYI3|EQI*P?c?xL+mGcgph;GkPoCVAb7>dnW`e7SyhEO!XY=MdSF59*1b?OdTv+q%lavcmliD2fl5UgBz||(x zmCf#@Yb|dqB25|dyFkJ4IW={+NqiaSgq~&m;kOg5t^NIL=3O1&a<4*(QtHNK7=e$G zsCv(f^+A6u+d>2!r{0!wgM&#YnhYa)(p^7zOm{pfFvt+O3ko1IYY$fg{c0bl+I8Ql zepkVviU|oBSpvHB+q|FJ_TS9ur^SW^Q3!8q{>@T!(8As`A248wluyBFJAR%sF4Ji` z7qdWC*}dXc|BQr2JnjD69X+DOr%#{!y11PjzEL)HRFpi_BA%n^_X{mbKfPhZ38*WH z5HKv3$Q!7AZ9vB*^|B#M3Gz}6a71ord@3HuukDS*5n@oH2|rE|2F5lKJA+D@e1+51 z(mnljISlnLOK@6YT2D1`utf4L<YO`wZc(_UrR@Xib(y81sYA&e1YJi3>?q@XBIa$? z)6N6!q^FwBxSfy{0$WL>=W#_5|72f}QOe{HAMhGm;$xOr2((i{V{~+KI1_xq7EhQD-~^ZlNn#fQV5PkjoDZ>s@eZ_x5!Z=zpBm#{^Z*<)7j^A|7GfvH)ZjymeJjtDuE8{adj; zLLo=0!6XTUS6@IplZ1g6kF==a@{{y3X)gp!&CP8=R+q01#<;s-<4|~9d5T;ESWw~b zhry8Y2jp|mcWr~A2&Pt4W}V(V-TgEb3%LC(Q4wo4+Dk2p{r>&2kP^kalDVyDOWi62 zBB~3@UO^7zGRj=)p1pg;%7}_FgzCj&taB@--EC}b#gs(o_oBgaP8myiXqho!p<2Hg6TE*yjD^CU?zl zgm$o*HUlek0J6?VXSlWkygDf5gKCN?$nrVdumQ4!gC|!{7{%kSymuV zhan}@Oi-O6=olo7g7c`+7slV7WSMLI149$h^HZwsWoG1KrHaP(@AC?R!@{=nhaFxe z%Wk?9#SLUR&~g;|{I~z)W}|N*;s4cw7`1D}GHEEnHT7ycvSTzI+z^ z!IA(yIT;q|E7#HV?g55=%?ym}pb};6^yv*rNYI4}RI4KarB7YD)Z5jT(#wu23~k>I zSxSQ|N*ZpCT?p1rp=h_nyoO)=8YEO)YTT!&_XPJ6&T}IhlO_`oX+xbVFqlTvDxyR2tyFE1+0ev8|A7Z*fu`Szb1}qKR z_bHC%Ker7^C$78f+7m<&SdYSC3ZhY1jHD+|+5o>`c_Fqh99U&vws6n{kRd<+8X=QG z&lDb9Ak{`~JU|FTkXrRz&`ifh7iL;k?h&pfdeP{C%oJS}Wd-NkwUJwWa-nofFJE?) z5XuD-{g7Z(;DPcdA+%l=Utd|hiU=&KVE(@;Q>T_cb0!q)VPwD~p0rFt_*uiwt_s3} z`%v@~%w5jkuo(>p*Fk3X73SC+0P-M*kr@(&99O_JAkUs-N>3YeI}IjWMU2v^XHV-j z8~9m%P>>bmQ=R+v{ph_f;>VVWBhS6P%+(@^Jj|HQ|B;J7?%IY~K_%0VhHp4$RR2+n ziSw_zJgS|?ZnMjaI)1M-n|;NFPMEwJw=QAx$ueEZrXM&-qEwM(64Z3Jc(_0--qI8F zv{NA8V0klpB-9c7i2Ri%RR>2L9N#4B^sF(#Gh&$7y^84@9M>s&cB*W-m`$2A8NBIR zUr~T!e}sUbRp&8#7Q6y=ELmUvMng(w(qREbTF;sTxjkqQF)I=OBP29I1(~yDf3i&E z5}PHzqqRySqXuzfHJTgdv%|pe;fQd1P_@{oVQfdX5{Ephddlg>{(IyIzF4iSZw?U_ z&|FGFi zga=S}@W?Yt0cafP=;#>yHf@?%b@pp%FMv-X|KIL)W>~)mF*OEa|LEv_gxrJa6s^oI zg+)%k()0cMeuR=oci$Zfo$!BjYC=Ud(M*xZYHdaCi+9V*j$Q3D0=$f5D+~@JzoGXp zC(x~r25d!i1fMEfmJ-$|U*m@}+?W8)fnM+4m+m)6z_>~PKaM8Dg&y>x*c*s3sIzma zX_xg*>$$J#P-jC39>GXgoCL54L3Imjq$4Mq#-5qAKzKfda1 zJF4aS!U51pc>7wGnFAXlZUULKK!60gUq4h(V@U@8g5VMeNfW3-mF|vFp9v>iH_v+d z!MXRwrvm};JtHE@v^vh5=69|tfEu^;yaAh@mNryXeT1Z7}d*&7=OmYVKnL5qAgL#ySCucG7^fD{^r+5#-A;UsItM|9vK z_yUfQOGd7z*OB5xrM~JZq7vqAW2xM|ebGVe-NUniTBA$YNh;O?>S}E|HN>FVPU$q^ zDm17tDH}$@EUb?l)m#pvbUU1Dh-*<$id2An)heSc1(rJefo(s%Et#iADlwj5$L+u5 zDo&ars+6s0$S{yLn|M_B`oZ?$afTs3W|!7`ba%_}_zyP_7>E-FS?TzLE*N zYi}-B_xure>F>(0_w(1jAalw-4McULX3nhK`&(Y2+1cWa&m-!dAFlOq*K|`DJ z!P>+%i?LnwgAJGRLdD64WA8)tU=I0H1nv_N3ZX+GVvlt!#~_Iu(ifo=BswLFO2FXN z!EY4voQ4Tb1nVc`MYQ3qmFgE0oqiT-G==A|U@Z-4wF~mQfdY|}8f}G2&6O7aLQ&&H>E8K5dUlM(_QkSU&c48oJLQl&T4jX z78Yk4Dvw~=9udC)QAc9rh0qDRR}E32lm6iWoRwJ>$=dctza=N1^p`Az!k#>>MFk-R zA?QRMbDnApNeDg0c|pZ7mXQQnP`huP^@I1lW@JbJ7%FEUpq{9YV<$cXdKcRUY;Ylr zN(6R=&yjt;|AIA90uGTHg}PZPMJx~)&)Au1T-*z&LxY;08Pmxe+&0tzOWt3)Nk zjpb(hgzmEId8vPKMA#hL?@XcPX&rf(cj;|)VDj8j2S4JIVgauN0&Y9JCn8UT+|%Bz ztLsHux5jMv@VRT^-~=o6&UpIn>Ram>o#tUOunRGgk$hLzISsI=RVI}=D(f( z_+fnP*DA;{F|-x`NQ7RZwA=LWv9Hhn{E-LP;noq(>2G>PDQti;Es)~KNCII4^Q>)1 z2a?D)03)M8rKEHf8%6A15%c%lIsPcZ_JttIN-@fx9~#kiNMXP|Nnz*#IBzxHLBbrg z8L?%U2@HUECqfwX!$Rkt8kofq+gD-Br37X{h z8CwRF>3)@XS;MZB{F_ct3&LR=LHh#A95y5#`u8Pb@7~uFF?pS(v`AIbe^`D~7-816apwgJKYN_Wd3;`EpBvw>GM07?5>p}gCS36aQ zY&_x52(|@nH3%*ATP48 z$lqzT(g6YQcezdQPJ*XcnBt=&)G~2T7NXIcgoEC!&*vqQs5ib+OmS)}peHV=P~-)m zKXyzK%bYlG93ooa!oO-C-@bRWznYx>CQY_SMSWTxQ)oMx8o$|eq-Y6cYTv(qudhIJ zFx|zo=*Oq`qG+iI&d*;!Cs9zp_CI3PpZ+W=!|vc0Ap$Bb#kAPrp?gDFkqD7M{1DL7 z+joLX5aUJs43{mHrzJ+k_&nkUoD3r%mawe#X4|ZnR1No@5ciq?+fMgfK&WDLO~-WV z!T-N%@D6_p9GNDe2RUYYvrTPictrRwB6vs}E!}-)e#pCsDI!<{O-iQTrn=*wdi$H3 zDg>D3ACq}P39ndjAvC`=s|uO<60rw=0^Cxm?u6X=37DPrNqbH2q@0$(cLGR2ENTJh zy|Dq}4XS`J^V`&Q4^pQjj!1|>u`QB0a<1w5p4wnUoJjfyxL0$!COI{Pt%blZqL-7& zO{$k*%p@(wo_6D_euVVu+^?Ts-NNR4%!M^QJS2Ow@ahowjXKx9xuEM=L+PWjY@V=pq%Q#b)Jwi9-Wv%876}v!pt5!`FX*}Xoc2qW$nxAtOVAxVS^Sc;FAy2inkxi@ZnQCv zjK1LlC9av$zEOcnf5k8Az{`PyKA*X|SeHwPX+kT$j93Lw@)ED04!83#~J)6~dzl$_B zcMlJ=6ZAZ61~@}MDODLx;h0E_2h11Ht@>-J7HCgULAILP$9xrwQKQ%jKAy1;nT0CK ziyMjxM3g_U5W$ow7U^=S`hcYgfgQQ>g{df8QOR6GH`KQA@ZrM=qguM#8bIO<5-Ll* zQ6o!05|Ju$lr8YdL9HlK`pmP_x&|$rTK@_Glg^n3&5-YpXU^zZUfSvNTY~rf6jW+b zS0kJ6$qnu1+CpfCF`_}FNR~yRa2~H;zn%g;03CLVvWug>4bJz%g$wu%c5+BAB!PHa?PFRkiI!6N?mGTQ1dyshMkPf6gdAH4VpqG|ptk%O{Pr5a z8;bk1120T;HNw{KX+NYHk<;V&@#C4sXH~8`KW{~$@AB_`pjMK`Ex6c7evRrlk*oE& zr35~_IkyWaVnlGMqZ1dx-bQhn{>3}-rGTXbv-*|lD2qrQ2o?@!u0DGL6~2sx3dSW9 z(2ymkXw9X0K;;ifn6hjOZ$A`L+<_bmNOub$3E~_n9;LZVV2KC5;5Xn>`E|8rb(t|P z^TB9jaR?r2qfnN4`;MRL04*sHC7_A7FTp4G!q3V^56$!WoB=$!qp5am^z%%zcJ``<#U5D$utM)1o>MkstF9y>ye~_7Q#hrZUHeQ zYX+eTWMmHFK^^omeEd}AGI5S)0Yd|hS^{ZHZGc%(kv=iFS^7=T#5k`QXN+oB7& zeOn#QUKEzh7^p#p$oGNkPlcI~9YKKddf0WbJiU#nYd4wNCzZlUX-Fz93bDe5Ss;X% zm3s-N>}CMp4A0oLZ(lm`O9TfW>$JAY$-Q_n%JE)X5g7woiE9*H##Yfh$OskZI@5Uk zF4CtSq!+K=3jkg@{`qB(66e;0zQnajTRFRT;M9o`?!FW^Fii!B@rBgnvOT-zto4hA zrnDLh{4*pqVkh(3x2VR&(LsTpW#u>O;bNyr}P=)>qh+U?=5&WTb zu{rn%8E%V~Ek#O*5>}~1IxtRC!Zi}~6ke|kjn#ln$u&Y^(3c8Fh;Zo{(+!Ml`|AK5 zl-EW5`EIpw*V>MW^K%B+bStzfw*1q#SB!=C8viM?W_lOyPVK#}v~|MO9anwVx<5?~ zp8LLA<<-$ULT*pJz0}dlYUk8qGuuCEYCj%-5cAaG;zhImIp3?+uOId-@Z#gpw13`x zu8w`_US;|f#{l7`Fh%5(1RCjK5fS_>Txs;NmV-xCefmqhm}M+mO@Fx>Cl9Py!SI@Z zdeiM~N6jlqTym2rs;Li_Zr$2;!lX&!ueush<-hTp+cA+QOP;041!;sriqbtGf8{zl zoK$R(d@wwI1!@g^>NvESo>K(>9(pAmn-VMU5mWbx_=JrC88s(`9i^d8TR`MLv)S+&id6lobq!f3i;F)*T}dqrLo`6mU643M+VkxwLz zo$a@2(+EH?yj>8)<-EXYr&T+c^8xSK^cXk7LFDA z2BPDhzc1g?X3~IS*#PxkA^_#VWnJaIpf?@Q;=s@U4j8|MMfI`}PNbtSO;Wi)giCU} zcxJgCRMS7!pKr1PXK?!_RKA~3geLt|$gUVGugaehq%{1|KBBCCO?Q@tAL|oeONGo( zLpRC9O+aPw`}eYTLWFpVQ;>-imPz|Y)ZU(9ZQ;{QG-j$zJM4jnRsmW}qfHaZ8>Z-3V0{60WDdqvSyDvT~Qh@(zDsaP(^nwX;_Uk@(wh8S5Hhic%-@ zggkbc4iRfJX+I&u;FOSp?1J}7=6uqJ3dB3@GW}8P)rxpl-U=L8su}V1)79Mz z8X2j(GuIflSytJ(#5LZRehZb)F(V!O=P=>|b&9SQ6n;gzp4A0N^#GIQt*|wbeGCpj z+2ToL&!7~n>}y=;L^i`k4eZ{lmp4*Mnrv?uNwR_w)oFONChay z-@@OhMn`z9^MMgjgmT8laA985Z`QULwy~x1aE=Z6&Hk?BerA6Vsa?_a4&M*hu#g%+ z^xillcN8hr%T1pf%YY0&c`GmPM5&MEJ+yY>DWjN|u-*L_yngh`7j5b7iPI~6#X@OZ z$f<1Zxx7X%?RsM5Ovba$5L+mWqhymGFHNRHzsx;{s#8{`kt<%Y$!dVk{GBi-4h+RMK5WPxrkC2rSbF6CJ&{4c zsG^p7ZtSy5Hg!u(WsVHubNr;|%4BL`%;C%)rz|CvAW)edLzq=8wmVg&Xb)~0vBMaGvJ$X?<3;* zHs}w13!ih#k<>{)-cYL*fUlUndeHOS__NHHrb`GU05Y@+iP2_a%-i`H6XcdkD zufSC#w@k1C>yu`>goP)6ukOrX+Ae(a@*yfiB+_e_pO7dcK^tj^)XFVuZGW-bnfVpH zFn*%rjNHFVJGcq2kAsU+qzO5P%x}+IB`7Az14S8qS@%G+HqnOaC}p9G` z8^#hm8|=7cv;HI%3jJZxkY;Dkgopc-s#`XE%Az_3Iz-G&!z}g{u4Q?;v`2|lnooVl zs!O~iTgRE16smSfIU#IZxyLU6oHn(r0#ur_r*Vx99EDKQ9P+ZN|wFnMoaBUyQ77qs* zrsnXBW%yY9HHBO6cXUswPpEeZ!v&DLQ5!2)QcT5uxkee1iY#w6IJ=`2j&h-0f|Yk} zhAznj5eA7MbXICgia07MlfogH6QS~y5mOn-Al%Bd0)I~uh!FAk7BZ4mbo4dE zw&!C#ShpfM7`JLHha|oIW0^o$enpcs3apOio)f-u4<7Z`<7)X$w%g7e97IcL%AWZO)>h3fAo% z?m_c}LV&t_@lZ{@d)?8{gU-c$- z6_NvvOW4`lp&f88hgA^f0V(07%1`J9gOdj#0LH=5mkItls9o%*Ys3;=Qv_Dd)(Syex>UdWK!#7~N}h6y_98 zGMogF8jNC4fN@KGrKHBI0Z~QW&G0#AOv#AWP1YO=-V0_Wrd+a0 zh`;k%flm2-A-o7K%2t89#BQqcD;?~mos5n_rT`U+IlWtBC?qq6d`Y7J z0wi^{Kp6P4ibBwOdZ5EO+S6GYkB7;G}*C@Q7hbQx1L^PdFbl0 z995VS3n!=Ua$2D*excS$D41&3TbM~6kp`n?|r{uz*MGva&`fxO|%ZQePITXtF9h81d+Q_mWsEY+dyKfka2`&SK zLPSyziS;UyDp|e59GR?N0gl@GGgfvpHaodboUWLPX13U4_in9$E1r0aKWLcMVp;HI zhH#+f7&hAP=U0#9jshLRkMn07^PXx0tX!s-_~0@=32qOcXS>VLYruI*>>#?@#P{#k zGY%=Z2o0|WY=RI$^twII80;Nscu-tlg%v=Qq>!yju!^F01IH>Z3yhr(DJPzGH363T zBOzPG1_DfG&>#JRdlSJKHkA=!-jJ9K3L(h}gxM4L#c}u$y>pN!O+oC>Mvn+MRXn zIcrv13Al^OzK^&YQDnO5+p3U;`eplS&D8bIrOEX6y9eoDZb|D}5WPi1NB6MZ{bTfz z0i7v$u$|BYV+FO9O98qgphJrqiZo%)1+$~+z%#%L8i9rnOFIFR0u6%~$qEF_iexxx z%otp`v}F*KJcKJddn>ln;Y9&_(X>#pX zPOvOdEL=m4rvku78t&^(@)ubjZ;3ev-V*-ksIycQ(O0k9WAj5p5vIPB|H9j%>JKd3 zI8ohZ5K&H=z$?MieA5d=%IRM7NsYhB&T4Gi380yRngedVE&CVV8qfeS)kq8wY2@x- zsQ!W&lDU%~H%GO=-h`UGfV1_bL;sT3s|MpHph?y7Xiu?^X>(0)5xRjr3kWJaH8@IG zdbi-O@pz%243uIJLOpo*Ep+HbL(dss;6hZ>^3Qh7h^bp<) z;8K|Y@kE;JP;kWq?0j9guwYQ$Thv8@C-rs7i*>Yq)Ne}hFVk#lWptW z+;Bmuk3A{1dUsMtz5tMjKB!u88-`S zdptgW`%RbO8#ivWn>9-YKH!-sLEYX(Fu5K&rGtOMaeOG*P62^I%ho?frEs)4xF(om z(AoHgUfL#uIOJ%^gOlp*L(U>N1?ef_%la|?w@9cWWr4SWWEO!K&=atlRC4cM)Dl$% zUgyQqW=h2*gT?%WaH+pvbxKW+>vU%koTnYeD)aMv?-nM54zrFDg3o#TqR`W_ty_9( z6j}J`y%u{{iW0_|@2(qQ5tu^26Z?MV{Fo&@B=OZEQ2S7=t?kN{ABOJxa4#dnGbqTu zc~^a}{V~Myj`Ym|I@RUdlBuzTlxeT4%gVmSOmB5p(Y_jjsD{*)5G#TwW{9#K$K_s@ zSBjvmZK{JIS2oofxZ<0-~MOSzn$2K{!645rYht7t>6K! zY>ip@sW;zqRt8$U@V-%#;}1X1&5a(v`#c1%^|hZfWc};#-c=Ekg@tkYtP3>3ziL_A z26}Jyl0onhO^At4%f@mIqZ!I@>n@vHQgR)A7za=w0~S|qJbwDL>iCGsWHR55BYYu; z5gvrVYttHx1oWXs3vcku!ud(0=hKShf=_v-rQ%rBadU+Zqt7qqd>W@!PJJZnD}@~) za+>|9m?j%t?zmezXMjMOHN6W9K!7nuNHnHhrxsxTWMJ8Wwzs^Bej-+vSI9wZ$Hi~5 z(=t0h{ra5V;4ze~Isar(@y8=?UjT{^g1qu$0j>l4txk&s0)&VPT5sZViXTbXDGs07 zx!iiSikYgMm`U{w%63?}|Az`U3D_$j_@sF!5AYVq+!X7A_i&H^iS2$Y$7ER|tF;D> z%)x*Ig3R?F9my0%{+jE1Yp*^$4%WxZ)?rqG#$oG&cQR#8w32ZIo;nk3$?L3x9qhNf-Addrdlz`WvXht zb6o^t2m|T{bXZoeo~OsrqOQ$$N*D_(dYs^1=RW7rKlkrDYI;ZzrsZiWZV~9h2}jra z21GaFOv?sCgd%%sm4XndacP*jJp1SDCgJLHH~)_oV8=F&G~u{M?ELPBf+@YP>z^M+ z(GnP4r7G<{(lUBNRr(lMe|v^CTs?nVwwjQJf6;CXA!`@`ra68)qIy%aonAxY-}A5Q zYTk`tl*egL_`NXH)_fF)p{jcBT03q@UHjB`q#dnp%WEw4W!HMy#nTCbJyUnz`)iN3 zMafWXJb+Cq9%VP?4}i~aJ5P!T|Wrc~9UU=q+U1Dmg_n~DQLDQD38BN+H=A-~N_ESRoxMS54SmRx!PD*LBe9Ri`W zhp=^tTUCH)9I&!x_K2n|u%KUoc97+(T3Wl)e68}PAq|;U0ly;5i_Cs7DBq~Vu)j0H z`cX~MlQ9c_iX)4JP@iH53`PBh`gw0CE1^Gypu^JvJ*#)UQ(zWA9~5kvSgXjSBUQf4 zqr;TlU*q<$8Ojgds%$+E8$9S&eVj@KhB1jZ-&6)rY->CBvZAGx4iY#{ez8mJTv`y* zwIvmg9^h-~g>Xo*{>P^M=>^iHiKSika8+14tSm(7NsYq71>CsPs8XKzj=8_1 zTuUV8)V?C(BH?)h(p*$Am`DY@5?Y_dmBBV(Il?LRboV{>+OgK*Is z2rMttz+dkCLk|W~OI;gL`RwrBLiS;Z!my6jze0F{qMN*%+sOsmS0qFtfP$l?v6i#L zP5^3`Oh@-U_vvG);Ut&9YXlQYWLjIQY4Tpf#8yQ-L2DJvR1R%$=h-6zk{TPD`WIfX z9WR01%ck#OXAcdvbQiS4G7#Fg@BXmxK|-X64v|WLk)mxv@3MyIl*VJPT*_5X<}6T^ zOHOT^=SYc*5B$#L0ZS=#WLQ$bNwtofGUu%R4Rb2Z!uU6D7O8t%@M!9-A6}T3mbTq! z{FkDvQN>|jnwQVy1;}u&_sP!)92FkSCCMRMvLwCcujfyn2GRcYJY%@mn{##_>&t|? z+KqA3HCam}xG~!9yHooSg$xd6V5|Im(4`x%)?BB)4cgYk(ph)#Dh0r!b7aLChANoW zq+#>$UR1Kr%6+0xmePQsAmUufgbb*U+$y7g&ORG&Mx&6DV)=H9Oj#2qh4{XrxgNPf z_tp7lfO2UBK7RdL`@GPIl)?*;zEx!UOcRQo4HK=*jo^X2d(!3o?lOrdW*FR3p+N<( zB~oqYIz7+w3Cwu#U}m>7@S2qSl+ngLHXtEx`RMT-tu3x9g*S11ocgW9-Mjwf(~~a# ze$~NH{~3+KVk=Ij=>aR-M*#Lws651|7+yV*hhY2Ry2~h}SdJm=54f5fu8Rk4>!J4%6%mEyQHSHPMQ5y2Z^#62&z_A?O)b&f zSzfPGJ8#S6c#15+HGwu1AKmH|!^??Kx_ZO<$>=3$eI#N5iip|pKC^0d6j7n?9NZB{ z$V8|LDRnFFSu{u-x$gHC8tSdUMA{HOEveuWdY;#+F8xt$?e{G>^a^Xlr?9eXza&w7DqbLWPR$(=!2&eV`yL`5~llEQ;SPJ4^kJ^bU% ztf_t0O1HB)G>Nd;*5bah97iL0JIFKrqsvFL^v25siyNs%NNv=!V#3 z7JZJ~O$FImjra3mzq2E{|1j|dadXt4Cvq5!iE#BsDz)dR50qi}jGXJ7Yw;s+-1>@I zUZJ1{U2NE<$#4BEi<|gi(I9iG#8??C0K58pq;4|eBiRB%5EFzD)NDI5tdMRy7+P9D z@8uMA%`dVCTGiRtRtUqXj;}EVU<33Eo8DKqv8df;sc&PKam>#zxy6q+JvKbQy8KM! z_D6K|;z$K1HT;^1UX`Wyjhq(V7JATbN2ez-jihx$4Bco+ZnLai=i;82Fj#~*WCgl%aA3=kpZ^_r$8g*g*Xaz*`eP1 zoh`vZaB5GMNk6_SrN0`T4xOeb`=9upvE`h}0u~2aBP1Hh=+i_Kd~Kmla0Oj`fZyCv zRG?Xq*YY-@$CEd1-b=K0>#>2yfKpR6|I2&#s#M3dT3Z+nteCS^ThV8JyluDiJ9j-0 zTPSKPhgQ7ncZw?h2TO^&|2X?M$iE0jP;P0KJ!ZI!>5oGn8W`w>E}qTY^VbhAb|Vh- zu7sX$%Z0+ZWs%WudiO$tG-TC)d`}ka+;QmlWz6Y>%4vvKNoo2&d)xKjKI$>H+;>5u zf@J8SQXeO-jCHw=)0m@$66*W%Anl0oeX!jBXEL5rk`XP8F$YQ19{?>>LD)NG<~#4+ zy;~}3{;$GSp}r970~s_gExmW=PUGMcB2|?;2`)04?od1)1SO`xT{yI@jb8bo*tL)E za!k5kc*DOtZ*lg)&ra9%&}BcWR#yN19_NR&MN@+Lf-7>rUjN~=h~R47Dr0iP%!XrSWWWw5reBH4K<#>@mYF6#*T zLPEn6-*5Az1#g*1m@zao1U(fiDAe(jyS9I5&JB`j9~_T`8%F~sP@>H3Qtm|RPA&z$ ze+5Q1c>Tvt-!_>M86@F~0}R!RFB~BuKRXb<398p~JT@ zj0@Q)RxIDpMA4IE=a-5KgjUuq=lh%Hh3McJeANOJaCAC}(6i-1^$lW;OGWj?>T0=# zGnOy`4-?B@4gvBBJbbo6c*Pl2QKr-BJFd~*mp+PS5GpBUjij~cpQZR@`?#|J1T!w! zdD3EC4%oB*ZC0jN9+4^p!i@O}d*h>SA=xi)$_oJ~o3`{O>%IUM(VC@NUzK&xeqXfC zl|W%?<}_t9l+xE9V&Ui(nx5x9XE9v{H|~vs((~4u^>5Y& z%|sLi0W~Y5$NXEf|Fme|a@G-GM_#@TDty?%j?foatdUcjZh}WwgeQUt1-`7pFK1kR90v@<~mM+e~NDx zqF^pp$mP^mY3n$cHK>-w3|)GyviR>GE~an9)80!L&g90^U8Vt{LwSM`;pQrvpk z?f9y=cqav@W0yWqa+Kp9kJAShPWxUmsbk3Q@9N8BO}A!`D^;7~lS@|6>Ag*!U1ckP z5n`##(Z}w2S-CrLiG%an3YQIjb=luX+oJ7ZB#lhk8pTd#M+K8Su3LSh)!k2I-X(>x z5x4ztH~+##C3~&h8y~bf&3K4|)fVwF#le#KsaGF9Gy&cOFUxX^OBmTnyKlopm`Q0% zK{x-Y%%KPeyWd;87Bh_PfOiGd*_x?t*SWHt5P(8m+(HzPMXw@&8jqf*Lr&xy2oySpy_j4ZPY5I_nTv~`I^3BG<-2%>g4BG9 zSSY*hxyH1)~Od}r|NUDUivzb(4;SymIqef}M70yW$Wmzs782|aAJoa-R68uFQaaqB>w4Zjn~Nl` z_8sh~h|BP9lA;6-NEBzZTh_++_)Vn&PGXO!r{`ID~zW77*TD? zy-H(%4DIv%VV81K3qIj#xtl0skHv(D)Q~D?IZV>@OPluR#0lVVC{O2>4J0kt#jMn& zg{qH1E_J0U$w@D6pmP!e_<)wNt!iI7r2Dha?7j6(+rSB4fF!7A|MO?|sI#9a4*9lf@a|$>r zvNRR#f*5Cr6X5FALB&g~dh^REj>Sz+#{O_V;R-OsaVm9wY#&=6e^HvRR&!m&jkdu>qO#9==0+z@TNi1BWcgU(;?BJv61wxIB0|>zr ztaLXFT5gZbW)`;7Hf*?_?6!b?(i}s84$wN*qVG^)n#t@(}hcii$sn>MW;gNh%A)*WN9wQ`^7 zF_(B7yLZpEnIS|(J}t^KHikdO4i1ruNE?9Km=lz`DHZ@g7DN(^#DkNSWU^B!c-e|x z;}8-cv;ybvAJ>QO_xg<^=>}Tap`6U9vX*~-*R{{FUKo(7D{)Z2~ zi2tT!*=oS%Hp8;UzV;HZmH7EUxq4OIETN6qHad=@Ci({P{8|1qqPN>#^SmQ){jA?c zxb~0rLFi-gF%vSCdQL_lGI=smkkBmsojUor%}l9gyPnN>dDx``#%a?7LJjLisTKM3 z1JW7keDQ6=_M3l3vLKe+G^*vp|{r#BH^8Lhd)5#D5ZRUQuBq6A*xbTa zJo4lE<)fZszC-w`4*Nv82pepiqryvIuzd8p>$ST%0H=ua%p%**8-^PQR6@?3-WEPn zMJz}i&+Juw$YB}%$HLECjMZCcE-TSq)(jysyxl(kCP)N8k8x@g|2b0sKq5R2xklva)SE>H2Q+Wrx#KWHB^_T~bT_z_iZZkRp)5dO zq=3@E!w9yWL+k)Nk^Y6h$NBZfk%1Ph4G?fkn@T*wo{Hf$v&bQ(Tfm+T=1E@0X7T$07T65}yh zXw0FO8C7O8gt5W4D=Nx3u1Mc&z&V~g;@E8u-W32#Q@z%sbe=THH@Ot0wwO!NGj>9F z1dYo`u*>Q?#lf&!Xq{ME$Q0aV-O+`;KuDNqyLu<$#k4coC+T2NN(8L2W0w>YB@B+F zS?{1z4KW(vl+UlQKKfbs{~kR?fjN8>5GmsEEfP6_{Oyw2-46|1ziQSb-7RXr3zr1Y z$)HX>z`(!RvNA3DGDA>s=^}$egKARc79#`HB9E>8kNhc}Cg*ZA*vhd1YRhET>pv;+ zH>Q0@w|R&5IxA#Ha*A11TifpX`wt5TZmrYzXY<6H`sdt&sDhaC>n}q}MwfL4^+ATl6$!N|(Y5t!? zE!LjX$#UXl2!z2gfJGS&5X_qcsF-&oiZJ-g-yY=#4$-3^At?|wWBzn?4XwZOjf+u_ z9=F7;9Iw;COrP>FzU6Og%B%B(%>uIV=o9~~9)Ss%Aepuz>D8(yzF+6r##OK=CCS%C>Lw{G}G2ZZi8qP1<|T-ySl%$+6>UEq&IKu6u~jYz#ty z?iJ=NERyB}M=$`5$PF`Zx1-+bY-qUMsJig&+hnBwXsE1{`gG~yUGqS1aYDflHLsS;!PAbbM!24fMRx!@Vok2B;jP zi~1p{>>^(gpoDQT89#s>l41(2H3K!aFBR9RLswt z#5?6FF!Z@1r2UdZ8H?6qG%6B^5pLNaiJMwLt^&Hxsmx0UZo zxv4-P{hHUKb!d@y|IQt!$T?4@B<*i9MmxJ7qqw;}DnC_ia=dzgN|7?9#T_>eZdvT3 zaY`Hf>GuCyAt*?Z7iV@rM-$pwH}nK8hpZe8XQ}}^3qj4hUmLKMx>%OYKr73z0kF*J z==VM^$2_!hhg1~>52X^}VlTxO>orB{4%Ls0c+^R=%|%OM8;U6_!Sm>N50r$M?Z_-k z|4*yYr8;da3^e6{%aMof7D*OV4d+;vlm4*2d|x34%#y@XuUz7Z&_CJEZWXz z>jmX;iy4dVHXV4x-(RtQc*D8}JuW+=pyXX`XX& zMLj47QqjnKk7ZeXtu+15e)#9a|8N0NOhZf)(_E=DVOD}l?x1X-yG*`0ZgSh520~m4 zo48##4NTYRD(!J?@9W_jqHj0TE&fmO(7fmPH3BNjL4l6&O+UWc3XqIPL^^~=~iARpi z^;$T-vc_tkor3=DC1fSm?VgM!jwzFnsYXo#K(Nr!h+A~ftJlXN_H{i4wwwX*i50$bwMa#%T`pUm8*^^N=zjEvV zg09r>xIfDf!y_1fjUk$~VE5V0L*09Nu*+hzzEwG>iG|hF+93vpR=-%^C)EKYaYe&1 zZg(DFNdkgi{qpFHx!r?0D&RHQveot<_Zy{+Lx?gFTSfeBemz;8eeL7Z3$UTkeMG#o zzo$XH3v)~IPSb`K2W4fD!hwA$WsdV#&)9wS!Gn%HBEOIEs7=XVb&b)0FsZJ6oOT^} zZt041=lhOnGGiE+pePN5e=O!zC>^!eSIt?;zj&S2%@h2x6;v^skNZ-Ybf!@TOAO_( zMu2@ndm+S%Ab#=ZI7P7r=X|$evO|*@jv+X;6f+#{h5Ac~dw$)<_<+4bY)Z$Bbo1uT z!tExSy!^hyM~e-0{PY!+sA5k5#wfv;qnPWo#5*vs9X>j+aXxY`EZ-K!>pd5Kz=NZ8 zxAu(N@N4(M{QV$ryd2SoK=7sdRy0fj)ISDA)pv~t+x$Mde+EDHN`G?<8HJ)F6(L5z3v0m7hCb|x zeujaGtkAghA|T}g)%U<&IY<-Wk`g6a36*z<_8Fek(u}Da_#Rj&4!z3={}PLF6ledU zQ^3BIYag{v(i1AiZ^5bO#>RW1TcPM{S({1_mx@hDDHfYO+R=2q)wsoBpdxzqo_)Om zYO9XVZp{A;u$vMa6Eh>Bg@)Z7^LA-Xtt`po7XBBOCs%M+?iTS#wQPz{R$nf#_R;)0 z@oHuT##6G5i1pQ#lRj3M6j3sy37X3fj(eP00JVwE>HP1210# zFCe$rG15~iq-<)b-C@_kH+`?w^?vuRq(tk)drJuY|H0mr&DJ2idyk=RKd%|gAwO6) zyo+3Gf0j3KN&gln^r7y<3XP*CK>oMuVDrS@GeFR0waDYhF*$N4+D(lsuds6taqUw# z(dJ9-i-N;zG<6#EeUvm&Ki3qY1jDZOneL=O7|9J~8D_trB9b!-{}|V(JeniQOz&zy z*NLMy{A!_q`S-CEYQWbmAy9Uxo_VsB+!a$RQ13+dxL^*1Su317Ls#CTMSwt?i5~) zTW(>zg{6#e+R^iAp7;r--*9`ny_qLw{RY$o->x@NI|lT_vraHOwP{A<)y>D2ojVG^ zfk~ZWBelvGlijXoP)Q0eh(0wk`Sz}Bt7A4~nqT)AP(N!%!>oekrG~FB#c!O!po<_D zpEpQpbwsOv9)Krud+5k*o4nM|{paaMCj2SufBMXN`sw4x_?#|%Abv}0EsQ!T_2_q6 zBVu5fCX11lX7qG2`@h)3s8~gd#3!3SYHmc+OyYTPU zQxF9&H))6=YaLDFbQCGfj_b8aq<)3ta`%#brF-eC%NH_hLJNYZj`u>54x192xO{N0 zUX3_oz-Yvx#ff>w-e&0JH(AFi(_=&20?V5^GiENF)z?4qXCq@eTp)D@E?Qz0mC7Jq zZ_)>tCG#iEXPA6xZdk&Xm(p4lw0q2EkzA$=wZ9ljGtV_%!1lvirkhvk2edY%r>Eop znd#2Y0FIU20(3zi+86xQtmQ{CxcTTl8Tge7ih2XAYS;RLc4W7{s{KxbA&cBbtX^c% z7DTV(ul7AYUJQK`{#g&cD_FomM@&}d9p7NZZy5!bH6*V zw~QfeaA3vd9Demcw*-Ww%sAejXPk`!!H8`9Kg}HuPlA1X?-mM&gB~kX3s~%q3qr+58U|z1(f%bN^I8HUc_2W10oBe8E zDwDOogWRpCt8u>pIUWwNl29Y7{{HJA{I_Y*xEDzV7NZZ4#Z7fJYe6N&qY@06`NVJKPy3Q*bSPV_m1is)tWwRTbf+OD5EA#nw(1=&&slG zZb#;>U2n(Tr}v;?X~vsgq?(ZOjJ9VxIQ?l=ybx~NaZ&(%cIxk(J-2uO#JO+lTL=Cb zGs&dJX_YN9#0RPub&@z?3m}QCH?GNVDCX1MAO&Y+&pW&;V|H&kS)LL$~x4Nbvdzg z3k+!N6$8p1-y-QwFYUMHu^9edg-o_I?_wKXj~G2*nUT4s|CXnH#>%!S$j}0EfIV*q zVt#r0gQH(g0Zb3*(&@@^;%*5s4leq@N4d;e%=cs%l;VsiHaTM2#99Z^Az-i|?u!&l z;HtcL`ZSWzX;TI#V{#i8}V~Gwc2VDjo2Y^+c-m!q4lE{ouu^UnFw7;rD3h6uI zKp2p7THU{2?-n^()Ya9QWmcvCwz#$XR!GvWTLJ#P3=MnCKNGdLL(31F7lcOMc-HUv zwidJWheQVCbT>EEx7~f?ckay0fZIv=spHMh8IBcO_UJ@=Nz8C%92?BV%dGy-E9bLfDSUoJqK%T@F?Yr|B<)jbafLXSmf2*#bLn zo+ksTw$o1?Ukh5%{!mtDN_yDD$(_Lj98)U;WpbqPKoXW3Rz$bF&+tE#r#T`!nj)tuCu`L9T#q=KpL^vCYxJ+|2C#)T@e( zL!<3aB_w2!T1FV9GM1Lx1@t0{+W4wueO1x+5mZ)1hss-r}NDu$n@OGgx> zxQY5$L}LVcvyO(o;fHh$BJx;%1F$L1DrW|(lz=%2@H(ksDrp1@XT%Bd*-7Uq0KzM} zD8UM1sOzjd^c&CgJ0JWQm4i$Y2@8LX)If&G?vcG#{)P%05$oRa?NyngV)#aXerS*a z6H&i|xCHM%Z>goM=w1JHLC4oBAC#64nden-k~aa!u?4UVuZpn$Y(PVP`+dxjw1c%! zIZtD8&j0T|?DLZJIv}iLN;9YJ2J@8F&KqNvZ{qbaCp?YABk3nF*epzUi@j)a%7?5h zkl_f!8K_3-fA7MBXU`6d9T?OOGR5mo3SI7cvd-!^rR2ji3(XlURty;;E1zaPZZ>VI z;Qk1edU66qU=LSkvBum+VxS3i*2v1LjqsVM#Lmvov~xUAOAcXI*quR@!nvhU8#r*_ zV%=U&faOuKbKKr&_vyTCGX?Lvz>fJ#`g|Fdb}BjcXOIU_SE0qU8r+7CQR0e~Jgk-x zjb|*}@Oze>-JTOC`cG<@B4q-A1Nrf$C`sU^(U(Q(jqT8}<4Sdv=*UQ{=)2M~7aQny z<&>k^m~0z;SC;31eOf_;8dT9G*?s{ZqrE5ppT>G$BS8Ga%>u1#_$5@KqT#4<6FlUy9A`Yx<4(d zI--YJ5m!sF+PuqaCog{#`Q+(S@mpc0e4RQ|ynU$sSMJ^fF5sFS*7SBn-t=vk-f)-% zk|!g1(fhM*Sw_s9Y(^pbXLotQIua54g29Phr)c6pzitFJW1_wFrIZZi-Jf)a=)P9h=)7g=_302{1ZS4q zPq@%W7)Um=wC!M6pHoPbY6UG>Fbd&KQ{nDlHe9Nsr?=l>%_X4A{8SI*^~?OS?__5B zgjj_tq~2eXo^JW2q;OTHx9YBnb%m#5nr^f2#Jk+%u!$egckHG=J3xf51A`AyO;k5x zgp{APTkKYX>GB(b?FWB?%z;y#igAYx?r=Ae&p-0##=CQ zi8&U|QtiUhG>x-+(xc_hHIaQut)wGC;|@M;Q`j1eiP!+Y(KF=F0u$PNh+5)_UzmE9 zC_uv@*4JDLS$DX~!c*VA-j)w@ZTr{+?L;CF>hO0tqxcFT>0a@q-|kW!@JV_tu_2_^ zU3jFMVWlX`KnIbX`cTL14W4Ke{<<;+j z^_`dMk?P-Bg1JKN;kUke^BpLf-_N$2!~Q7IV#(-Mr1Q9UJltEMXhFGz^S9hnMA`O` z=5DAjH*u=^!ITzyPrW}&eo1#iuOMslxEhm#t@m}aR~isnw$~=0$n???^$>6mI+gCU zeGDe`VOE107x8ip z&VggPFFJEw=!2p>jth(*Q zK#ycfkZl0ei94;{U{6Tm5&|C1+WUr~uUO!t2onLktX5)!y0+u2phY<-3=fTVYl{p= z7;DE8682Egqyq;2Ty!6Sjly^)+CW3p43lR1yN)0AJaaps3OjzpC>s4aeMCL^WGxob7k4^NHJ(+u?B9DKjkei~iyKi0 za${qGey7c<;z}xjg?45Xga5(!nBph|p3NKyS`3JO`z2g~(?dDQ<*%=R0w{BKH*fX5 z)HWz0R!sIEB^g`Hl;F)Ga%>2FPgWc+SX31;Me~e3tWF5+;&A7vWhRD$^tQqhM|>oP zDoGmDfnif-Hu>1I28S~7ja3lqijl1+J9bbTx2d?3D}CD3^*#f97Vz;mJ1bwnDn~)o z^j!>Hn1hK5<)g2*@?b`_J;#kZ8n{O#d;(QL0|g8y?&_&Tp0T_s>z3p^!zcQU$&j$= z$q)g-hW;|O5vibo(E$k1YH6B!Qqxf#QsYkE zjB_w3RUX#s%Ed>|e;f%-biY~is^Q^X-4Ac^yK~uZc0%IHh{U7NP-sj=s4H6@nM5uK zIWpLwsz}@T;@5xjtBoJ7{o>xfy_-Q*Jaa!Tl`NlySh%m#T&#Duj7-iT~Vr7YhSw4DPpISn$PhEk%P|nxO36-*!qic@A`f@&`fVte=l_% z-eE;=%w$twj6K^Ju^rZEee8PN^-Lz&cK25n1Lt#zPQ+qdW#?+||x7iCH z9#b>f4~3uhn@%;)M!I+QK8y>h*t?05a>jTi1>6YUbW->VMoh;cn={qMZWJ46NIEqK zJ15dXo$xu-a{%3+tiR)S`7ooyDdA9XhS_fJqDTw4*`l`+mkV;HXjd5!`zED4ka>N~ z71rqNA!Dl4?9y*@9jHP;C~R6`3ATPjA?gVhBV_?+!jN7O-GdTJ1Lzp@fPj;(`VRsv zmA%jd!5QtHfGu;9iZg@B8_2~t9?6~irD4&PM%M*)a@Hu9!==rJ~p>3HQx2esOXznIJ?`v6aKP82RFC{NevbOJ)e+C5%YF24AC7n%!s_* z^vKS6%uHIL375(ie@HP0qG2-43coF)S1}Bph}l60ow+T5E}2WVG7s)QAuITkQ!u%< zC+Q!J5~Kkm%=GnDmTD=xp;fbr%Vq{6Pt`VBSMcNwcUVZAZoaS6|4x6K*#HfO_W$RSGE!d|!UHIYfdsW+vQ@buq`zdNydgt}8p02epoZ{5T;DOLrUEkQlW*=85hT1=UG;ILAv2d>Cca?0?)h7T&&lYOr zboht#zhU+lr?udzP^a$vaYfo}xYZ0anG8}8W1rUGg-b-DR7uo8P56fE3`&P*jdQQs z%9j{LKW6qWlZ3PPp!30pGS~n0FX)~+a!RJKUSK;Y<;5yG=Zxl7j0)0G>4{C3Y&;VX zamS9u3)U@cP@~#s&;9@50#yAJW21iuZlWlQ>}92SB7(k`Cn>lYXChDiJOsUT+9D;j zv0E=)8Y!+K;^K%5kc=JO`=8((V3z;vTkSx5m@dc#PD&D1#Gr+0KtTc78;C-{uHK+X zv_kW9B26*7_C~kCBYX4tvt>lBmO_fxo6K#)w~e<~3JGZWhAYK>d83 z>7F>DlFS~x-=yq)4d9vq?RNY(IOeRy9l19+(popBo6Q0$Rie2VKmFiGgicC;RX*)2E;|S$mH)W{0=5rdw)5FVaouRh*CTaK_S{!@q9^OBA zB2S;BZ5p;C91)ak;$m%iLM%_&MakrbSQ9w_x00Xa2GSj{LtIQHwyf-~Emcq^Y5>wZzxGe9;VzCg+_H4mSnF`u?y(%Ys#-;MET z@DGj{9P2b@4M>)FtxDmoSFmxSZL3DdpZi7X`rf^3A#8WqNaKEIZ);?M5{f9#@P)W> zX_kYg^7$~$)jo+Pmr}Ay*ERP}Q+smd{1I5i*uyf0K@e@es8p)&UwxJ)$2w@WEj-dQ zbwtrVSph76&*+)a5>OtMsFVbRJFkQH1v%VBCy|TrKVX`9~Ed^kyVDB7Nne zB}YF<_!B%m)H1KiH2?F&S!dDi32Bg8cPs16+q7h!*AxRng5Ni)lk%?xYIGP$dG>?S z%2J2hv@Tno^>tl%^pN5sDn`L>hIzwIYP{>cH2LC=D)*3;{S`NGiCfCx3|vNF9&%Ie zw~V&$$7pnhOx<4eYTR8h-j6IXQFX~&?2`E{I(JWDcwe_)Gzzlw0cyTw *yPIEH0 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 B0o4Ei diff --git a/example/gcc/AfterInstall/CMakeLists.txt b/example/gcc/AfterInstall/CMakeLists.txt index 5931a007..04a8cd7a 100644 --- a/example/gcc/AfterInstall/CMakeLists.txt +++ b/example/gcc/AfterInstall/CMakeLists.txt @@ -13,6 +13,7 @@ project(simple) find_package(fmt_package NAMES "fmt" REQUIRED) find_package(spdlog_package NAMES "spdlog" REQUIRED) find_package(flatbuffers_package NAMES "Flatbuffers" "flatbuffers" REQUIRED) +find_package(nlohmann_json_package NAMES "nlohmann_json" REQUIRED) find_package(taskflow_package NAMES "Taskflow" "taskflow" REQUIRED) find_package(tl_optional_package NAMES "tl-optional" REQUIRED) find_package(CLI11_package NAMES "CLI11" REQUIRED) @@ -23,6 +24,7 @@ find_package(buildcc_package NAMES "buildcc" REQUIRED) message("Find package: ${fmt_package_DIR}") message("Find package: ${spdlog_package_DIR}") message("Find package: ${flatbuffers_package_DIR}") +message("Find package: ${nlohmann_json_package_DIR}") message("Find package: ${tl_optional_package_DIR}") message("Find package: ${taskflow_package_DIR}") message("Find package: ${CLI11_package_DIR}") diff --git a/third_party/json b/third_party/json new file mode 160000 index 00000000..bc889afb --- /dev/null +++ b/third_party/json @@ -0,0 +1 @@ +Subproject commit bc889afb4c5bf1c0d8ee29ef35eaaf4c8bef8a5d From 1fded037aa4d033c3e1aa0ae486fb24c317f8420 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Fri, 4 Nov 2022 03:30:51 -0700 Subject: [PATCH 29/35] [Serialization] Custom Generator unit tests (#224) --- .../target/include/target/custom_generator.h | 32 +-- .../target/include/target/file_generator.h | 4 +- .../target/interface/builder_interface.h | 4 +- .../include/target/template_generator.h | 4 +- .../src/custom_generator/custom_generator.cpp | 92 +++---- .../target/src/generator/file_generator.cpp | 4 +- .../src/generator/template_generator.cpp | 4 +- .../src/target/friend/compile_object.cpp | 3 +- buildcc/lib/target/src/target/tasks.cpp | 8 +- buildcc/lib/target/test/path/test_path.cpp | 36 ++- .../test/target/test_builder_interface.cpp | 32 +-- .../test/target/test_custom_generator.cpp | 240 +++++++++--------- buildcc/schema/cmake/schema.cmake | 1 + .../include/schema/custom_generator_schema.h | 82 ++++++ .../schema/custom_generator_serialization.h | 63 +---- buildcc/schema/include/schema/path.h | 70 ++--- .../include/schema/private/schema_util.h | 9 +- .../src/custom_generator_serialization.cpp | 19 +- .../test_custom_generator_serialization.cpp | 25 ++ cmake/coverage/lcov.cmake | 1 + 20 files changed, 376 insertions(+), 357 deletions(-) create mode 100644 buildcc/schema/include/schema/custom_generator_schema.h diff --git a/buildcc/lib/target/include/target/custom_generator.h b/buildcc/lib/target/include/target/custom_generator.h index c7558757..e0263419 100644 --- a/buildcc/lib/target/include/target/custom_generator.h +++ b/buildcc/lib/target/include/target/custom_generator.h @@ -86,21 +86,21 @@ class CustomBlobHandler { virtual std::vector Serialize() const = 0; }; -struct UserGenInfo : internal::CustomGeneratorSchema::IdInfo { +struct UserIdInfo : internal::CustomGeneratorSchema::IdInfo { fs_unordered_set inputs; GenerateCb generate_cb; std::shared_ptr blob_handler{nullptr}; }; struct UserCustomGeneratorSchema : public internal::CustomGeneratorSchema { - std::unordered_map gen_info_map; + std::unordered_map ids; void ConvertToInternal() { - for (auto &[id, gen_info] : gen_info_map) { - gen_info.internal_inputs = path_schema_convert( - gen_info.inputs, internal::Path::CreateExistingPath); - auto [_, success] = internal_ids.try_emplace(id, gen_info); - env::assert_fatal(success, fmt::format("Could not save {}", id)); + for (auto &[id_key, id_info] : ids) { + id_info.internal_inputs = path_schema_convert( + id_info.inputs, internal::Path::CreateExistingPath); + auto [_, success] = internal_ids.try_emplace(id_key, id_info); + env::assert_fatal(success, fmt::format("Could not save {}", id_key)); } } }; @@ -137,16 +137,16 @@ class CustomGenerator : public internal::BuilderInterface { * @param generate_cb User-defined generate callback to build outputs from the * provided inputs */ - void AddGenInfo(const std::string &id, - const std::unordered_set &inputs, - const std::unordered_set &outputs, - const GenerateCb &generate_cb, - std::shared_ptr blob_handler = nullptr); + void AddIdInfo(const std::string &id, + const std::unordered_set &inputs, + const std::unordered_set &outputs, + const GenerateCb &generate_cb, + std::shared_ptr blob_handler = nullptr); // TODO, Doc - void AddGroup(const std::string &group_id, - std::initializer_list ids, - const DependencyCb &dependency_cb = DependencyCb()); + void AddGroupInfo(const std::string &group_id, + std::initializer_list ids, + const DependencyCb &dependency_cb = DependencyCb()); // Callbacks /** @@ -233,7 +233,7 @@ class CustomGenerator : public internal::BuilderInterface { std::unordered_set ungrouped_ids_; std::mutex success_schema_mutex_; - std::unordered_map success_schema_; + std::unordered_map success_schema_; // Internal env::Command command_; diff --git a/buildcc/lib/target/include/target/file_generator.h b/buildcc/lib/target/include/target/file_generator.h index 3a359d87..e11b2b21 100644 --- a/buildcc/lib/target/include/target/file_generator.h +++ b/buildcc/lib/target/include/target/file_generator.h @@ -69,8 +69,8 @@ class FileGenerator : public CustomGenerator { // Restrict access to certain custom generator APIs private: using CustomGenerator::AddDependencyCb; - using CustomGenerator::AddGenInfo; - using CustomGenerator::AddGroup; + using CustomGenerator::AddGroupInfo; + using CustomGenerator::AddIdInfo; using CustomGenerator::Build; private: diff --git a/buildcc/lib/target/include/target/interface/builder_interface.h b/buildcc/lib/target/include/target/interface/builder_interface.h index 90eaa861..40184f6f 100644 --- a/buildcc/lib/target/include/target/interface/builder_interface.h +++ b/buildcc/lib/target/include/target/interface/builder_interface.h @@ -74,8 +74,8 @@ inline PathState CheckPaths(const internal::path_unordered_set &previous_path, state = PathState::kAdded; } else { const bool updated_cond = - (p.GetLastWriteTimestamp() > - find->GetLastWriteTimestamp()); + (p.last_write_timestamp > + find->last_write_timestamp); if (updated_cond) { dirty = true; state = PathState::kUpdated; diff --git a/buildcc/lib/target/include/target/template_generator.h b/buildcc/lib/target/include/target/template_generator.h index 6521be2d..79706a4c 100644 --- a/buildcc/lib/target/include/target/template_generator.h +++ b/buildcc/lib/target/include/target/template_generator.h @@ -43,8 +43,8 @@ class TemplateGenerator : public CustomGenerator { // Restrict access to certain custom generator APIs private: using CustomGenerator::AddDependencyCb; - using CustomGenerator::AddGenInfo; - using CustomGenerator::AddGroup; + using CustomGenerator::AddGroupInfo; + using CustomGenerator::AddIdInfo; using CustomGenerator::Build; private: diff --git a/buildcc/lib/target/src/custom_generator/custom_generator.cpp b/buildcc/lib/target/src/custom_generator/custom_generator.cpp index 6e466b1e..c7cb8725 100644 --- a/buildcc/lib/target/src/custom_generator/custom_generator.cpp +++ b/buildcc/lib/target/src/custom_generator/custom_generator.cpp @@ -51,16 +51,16 @@ CustomGenerator::Get(const std::string &file_identifier) const { return command_.GetDefaultValueByKey(file_identifier); } -void CustomGenerator::AddGenInfo( +void CustomGenerator::AddIdInfo( const std::string &id, const std::unordered_set &inputs, const std::unordered_set &outputs, const GenerateCb &generate_cb, std::shared_ptr blob_handler) { - env::assert_fatal(user_.gen_info_map.find(id) == user_.gen_info_map.end(), + env::assert_fatal(user_.ids.find(id) == user_.ids.end(), fmt::format("Duplicate id {} detected", id)); ASSERT_FATAL(generate_cb, "Invalid callback provided"); - UserGenInfo schema; + UserIdInfo schema; for (const auto &i : inputs) { fs::path input = string_as_path(command_.Construct(i)); schema.inputs.emplace(std::move(input)); @@ -71,17 +71,17 @@ void CustomGenerator::AddGenInfo( } schema.generate_cb = generate_cb; schema.blob_handler = std::move(blob_handler); - user_.gen_info_map.try_emplace(id, std::move(schema)); + user_.ids.try_emplace(id, std::move(schema)); ungrouped_ids_.emplace(id); } -void CustomGenerator::AddGroup(const std::string &group_id, - std::initializer_list ids, - const DependencyCb &dependency_cb) { +void CustomGenerator::AddGroupInfo(const std::string &group_id, + std::initializer_list ids, + const DependencyCb &dependency_cb) { // Verify that the ids exist // Remove those ids from ungrouped_ids for (const auto &id : ids) { - env::assert_fatal(user_.gen_info_map.find(id) != user_.gen_info_map.end(), + env::assert_fatal(user_.ids.find(id) != user_.ids.end(), fmt::format("Id '{}' is not found", id)); ungrouped_ids_.erase(id); } @@ -131,22 +131,22 @@ void CustomGenerator::BuildGenerate( std::unordered_set &gen_selected_ids, std::unordered_set &dummy_gen_selected_ids) { if (!serialization_.IsLoaded()) { - std::for_each( - user_.gen_info_map.begin(), user_.gen_info_map.end(), - [&](const auto &iter) { gen_selected_ids.insert(iter.first); }); + std::for_each(user_.ids.begin(), user_.ids.end(), [&](const auto &iter) { + gen_selected_ids.insert(iter.first); + }); dirty_ = true; } else { // DONE, Conditionally select internal_ids depending on what has // changed - const auto &prev_gen_info_map = serialization_.GetLoad().internal_ids; - const auto &curr_gen_info_map = user_.gen_info_map; + const auto &prev_ids = serialization_.GetLoad().internal_ids; + const auto &curr_ids = user_.ids; - // DONE, MAP REMOVED condition Check if prev_gen_info_map exists in - // curr_gen_info_map If prev_gen_info_map does not exist in - // curr_gen_info_map, has been removed from existing build We need this + // DONE, MAP REMOVED condition Check if prev_ids exists in + // curr_ids If prev_ids does not exist in + // curr_ids, has been removed from existing build We need this // condition to only set the dirty_ flag - for (const auto &[id, _] : prev_gen_info_map) { - if (curr_gen_info_map.find(id) == curr_gen_info_map.end()) { + for (const auto &[id, _] : prev_ids) { + if (curr_ids.find(id) == curr_ids.end()) { // MAP REMOVED condition IdRemoved(); dirty_ = true; @@ -154,11 +154,11 @@ void CustomGenerator::BuildGenerate( } } - // DONE, MAP ADDED condition Check if curr_gen_info_map exists in - // prev_gen_info_map If curr_gen_info_map does not exist in - // prev_gen_info_map, has been added to existing build - for (const auto &[id, _] : curr_gen_info_map) { - if (prev_gen_info_map.find(id) == prev_gen_info_map.end()) { + // DONE, MAP ADDED condition Check if curr_ids exists in + // prev_ids If curr_ids does not exist in + // prev_ids, has been added to existing build + for (const auto &[id, _] : curr_ids) { + if (prev_ids.find(id) == prev_ids.end()) { // MAP ADDED condition IdAdded(); gen_selected_ids.insert(id); @@ -232,8 +232,8 @@ void CustomGenerator::GenerateTask() { // Store dummy_selected and successfully run schema if (dirty_) { UserCustomGeneratorSchema user_final_schema; - user_final_schema.gen_info_map.insert(success_schema_.begin(), - success_schema_.end()); + user_final_schema.ids.insert(success_schema_.begin(), + success_schema_.end()); user_final_schema.ConvertToInternal(); serialization_.UpdateStore(user_final_schema); @@ -278,42 +278,44 @@ tf::Task CustomGenerator::CreateTaskRunner(tf::Subflow &subflow, bool build, void CustomGenerator::TaskRunner(bool run, const std::string &id) { // Convert - auto ¤t_gen_info = user_.gen_info_map.at(id); - current_gen_info.internal_inputs = internal::path_schema_convert( - current_gen_info.inputs, internal::Path::CreateExistingPath); - current_gen_info.userblob = - current_gen_info.blob_handler != nullptr - ? current_gen_info.blob_handler->GetSerializedData() - : std::vector(); + { + auto &curr_id_info = user_.ids.at(id); + curr_id_info.internal_inputs = internal::path_schema_convert( + curr_id_info.inputs, internal::Path::CreateExistingPath); + curr_id_info.userblob = curr_id_info.blob_handler != nullptr + ? curr_id_info.blob_handler->GetSerializedData() + : std::vector(); + } // Run - const auto ¤t_info = user_.gen_info_map.at(id); + const auto ¤t_id_info = user_.ids.at(id); bool rerun = false; if (run) { rerun = true; } else { const auto &previous_info = serialization_.GetLoad().internal_ids.at(id); - rerun = internal::CheckPaths(previous_info.internal_inputs, - current_info.internal_inputs) != - internal::PathState::kNoChange || - internal::CheckChanged(previous_info.outputs, current_info.outputs); - if (!rerun && current_info.blob_handler != nullptr) { - rerun = current_info.blob_handler->CheckChanged(previous_info.userblob, - current_info.userblob); + rerun = + internal::CheckPaths(previous_info.internal_inputs, + current_id_info.internal_inputs) != + internal::PathState::kNoChange || + internal::CheckChanged(previous_info.outputs, current_id_info.outputs); + if (!rerun && current_id_info.blob_handler != nullptr) { + rerun = current_id_info.blob_handler->CheckChanged( + previous_info.userblob, current_id_info.userblob); } } if (rerun) { dirty_ = true; - buildcc::CustomGeneratorContext ctx(command_, current_info.inputs, - current_info.outputs, - current_info.userblob); - bool success = current_info.generate_cb(ctx); + buildcc::CustomGeneratorContext ctx(command_, current_id_info.inputs, + current_id_info.outputs, + current_id_info.userblob); + bool success = current_id_info.generate_cb(ctx); env::assert_fatal(success, fmt::format("Generate Cb failed for id {}", id)); } std::scoped_lock guard(success_schema_mutex_); - success_schema_.try_emplace(id, current_info); + success_schema_.try_emplace(id, current_id_info); } } // namespace buildcc diff --git a/buildcc/lib/target/src/generator/file_generator.cpp b/buildcc/lib/target/src/generator/file_generator.cpp index 9f60aa96..7ec3deb2 100644 --- a/buildcc/lib/target/src/generator/file_generator.cpp +++ b/buildcc/lib/target/src/generator/file_generator.cpp @@ -111,8 +111,8 @@ void FileGenerator::AddCommand( } void FileGenerator::Build() { - AddGenInfo("Generate", inputs_, outputs_, FileGeneratorGenerateCb, - std::make_shared(commands_)); + AddIdInfo("Generate", inputs_, outputs_, FileGeneratorGenerateCb, + std::make_shared(commands_)); this->CustomGenerator::Build(); } diff --git a/buildcc/lib/target/src/generator/template_generator.cpp b/buildcc/lib/target/src/generator/template_generator.cpp index 4c6f2a1e..45cab89d 100644 --- a/buildcc/lib/target/src/generator/template_generator.cpp +++ b/buildcc/lib/target/src/generator/template_generator.cpp @@ -66,8 +66,8 @@ void TemplateGenerator::Build() { std::string name = string_as_path(ParsePattern(info.input_pattern)) .lexically_relative(Project::GetRootDir()) .string(); - AddGenInfo(name, {info.input_pattern}, {info.output_pattern}, - template_generate_cb); + AddIdInfo(name, {info.input_pattern}, {info.output_pattern}, + template_generate_cb); } this->CustomGenerator::Build(); } diff --git a/buildcc/lib/target/src/target/friend/compile_object.cpp b/buildcc/lib/target/src/target/friend/compile_object.cpp index 5fa43bc4..a20c36d8 100644 --- a/buildcc/lib/target/src/target/friend/compile_object.cpp +++ b/buildcc/lib/target/src/target/friend/compile_object.cpp @@ -254,8 +254,7 @@ void CompileObject::RecompileSources( target_.SourceAdded(); } else { // *2 Current file is updated - if (current_file.GetLastWriteTimestamp() > - iter->GetLastWriteTimestamp()) { + if (current_file.last_write_timestamp > iter->last_write_timestamp) { source_files.push_back(current_file); target_.dirty_ = true; target_.SourceUpdated(); diff --git a/buildcc/lib/target/src/target/tasks.cpp b/buildcc/lib/target/src/target/tasks.cpp index 98ba8f9c..50a59376 100644 --- a/buildcc/lib/target/src/target/tasks.cpp +++ b/buildcc/lib/target/src/target/tasks.cpp @@ -94,12 +94,12 @@ void CompileObject::Task() { for (const auto &s : selected_source_files) { std::string name = fmt::format( - "{}", s.GetPathname().lexically_relative(Project::GetRootDir())); + "{}", s.pathname.lexically_relative(Project::GetRootDir())); (void)subflow .emplace([this, s]() { try { - bool success = env::Command::Execute( - GetObjectData(s.GetPathname()).command); + bool success = + env::Command::Execute(GetObjectData(s.pathname).command); env::assert_fatal(success, "Could not compile source"); target_.serialization_.AddSource(s); } catch (...) { @@ -112,7 +112,7 @@ void CompileObject::Task() { // For graph generation for (const auto &ds : selected_dummy_source_files) { std::string name = fmt::format( - "{}", ds.GetPathname().lexically_relative(Project::GetRootDir())); + "{}", ds.pathname.lexically_relative(Project::GetRootDir())); (void)subflow.placeholder().name(name); } } catch (...) { diff --git a/buildcc/lib/target/test/path/test_path.cpp b/buildcc/lib/target/test/path/test_path.cpp index 19337a30..50249313 100644 --- a/buildcc/lib/target/test/path/test_path.cpp +++ b/buildcc/lib/target/test/path/test_path.cpp @@ -26,11 +26,11 @@ static const auto current_file_path = TEST(PathTestGroup, Path_ExistingPathStaticConstructor) { auto existing_path = buildcc::internal::Path::CreateExistingPath(current_file_path); - STRCMP_EQUAL(existing_path.GetPathname().string().c_str(), + STRCMP_EQUAL(existing_path.pathname.string().c_str(), current_file_path.string().c_str()); // * NOTE, Last write timestamp changes whenever we resave or re-download // This would not work well with Git - // UNSIGNED_LONGLONGS_EQUAL(existing_path.GetLastWriteTimestamp(), + // UNSIGNED_LONGLONGS_EQUAL(existing_path.last_write_timestamp, // 13623997187709551616ULL); } @@ -41,19 +41,18 @@ TEST(PathTestGroup, Path_ExistingPathStaticConstructor_ThrowFileException) { TEST(PathTestGroup, PathConstructor_NewPathStaticConstructor) { buildcc::internal::Path p = - buildcc::internal::Path::CreateNewPath("random_path_main.cpp", 12345ULL); - STRCMP_EQUAL(p.GetPathname().string().c_str(), "random_path_main.cpp"); - UNSIGNED_LONGLONGS_EQUAL(p.GetLastWriteTimestamp(), 12345ULL); + buildcc::internal::Path("random_path_main.cpp", 12345ULL); + STRCMP_EQUAL(p.pathname.string().c_str(), "random_path_main.cpp"); + UNSIGNED_LONGLONGS_EQUAL(p.last_write_timestamp, 12345ULL); } TEST(PathTestGroup, Path_EqualityOperator) { buildcc::internal::Path p = buildcc::internal::Path::CreateExistingPath(current_file_path); - STRCMP_EQUAL(p.GetPathname().string().c_str(), - current_file_path.string().c_str()); + STRCMP_EQUAL(p.pathname.string().c_str(), current_file_path.string().c_str()); buildcc::internal::Path newp = - buildcc::internal::Path::CreateNewPath(current_file_path, 12345ULL); + buildcc::internal::Path(current_file_path, 12345ULL); // NOTE, Equality does not match the last_write_timestamp // ONLY matches the string @@ -71,25 +70,24 @@ TEST(PathTestGroup, Path_UnorderedSet) { .insert(buildcc::internal::Path::CreateExistingPath( current_file_path)) .second); - CHECK_FALSE(unique_paths - .insert(buildcc::internal::Path::CreateNewPath( - current_file_path, 12345ULL)) - .second); - CHECK_TRUE(unique_paths - .insert(buildcc::internal::Path::CreateNewPath( - "random_path_main.cpp", 98765ULL)) - .second); + CHECK_FALSE( + unique_paths.insert(buildcc::internal::Path(current_file_path, 12345ULL)) + .second); + CHECK_TRUE( + unique_paths + .insert(buildcc::internal::Path("random_path_main.cpp", 98765ULL)) + .second); // Check finds // * NOTE, Only matches pathname CHECK_FALSE(unique_paths.find(buildcc::internal::Path::CreateExistingPath( current_file_path)) == unique_paths.end()); - CHECK_FALSE(unique_paths.find(buildcc::internal::Path::CreateNewPath( + CHECK_FALSE(unique_paths.find(buildcc::internal::Path( current_file_path, 1111ULL)) == unique_paths.end()); - CHECK_FALSE(unique_paths.find(buildcc::internal::Path::CreateNewPath( + CHECK_FALSE(unique_paths.find(buildcc::internal::Path( "random_path_main.cpp", 12345ULL)) == unique_paths.end()); - CHECK_TRUE(unique_paths.find(buildcc::internal::Path::CreateNewPath( + CHECK_TRUE(unique_paths.find(buildcc::internal::Path( "incorrect_path_main.cpp", 0000ULL)) == unique_paths.end()); } diff --git a/buildcc/lib/target/test/target/test_builder_interface.cpp b/buildcc/lib/target/test/target/test_builder_interface.cpp index ba1d02e9..5e59d9fe 100644 --- a/buildcc/lib/target/test/target/test_builder_interface.cpp +++ b/buildcc/lib/target/test/target/test_builder_interface.cpp @@ -76,12 +76,12 @@ TEST(TestBuilderInterfaceGroup, CheckPaths) { { auto pathstate = buildcc::internal::CheckPaths( { - buildcc::internal::Path::CreateNewPath("", 0x1234), - buildcc::internal::Path::CreateNewPath("v1", 0x2345), + buildcc::internal::Path("", 0x1234), + buildcc::internal::Path("v1", 0x2345), }, { - buildcc::internal::Path::CreateNewPath("", 0x1234), - buildcc::internal::Path::CreateNewPath("v1", 0x2345), + buildcc::internal::Path("", 0x1234), + buildcc::internal::Path("v1", 0x2345), }); CHECK_TRUE(pathstate == buildcc::internal::PathState::kNoChange); } @@ -89,11 +89,11 @@ TEST(TestBuilderInterfaceGroup, CheckPaths) { { auto pathstate = buildcc::internal::CheckPaths( { - buildcc::internal::Path::CreateNewPath("", 0x1234), - buildcc::internal::Path::CreateNewPath("v1", 0x2345), + buildcc::internal::Path("", 0x1234), + buildcc::internal::Path("v1", 0x2345), }, { - buildcc::internal::Path::CreateNewPath("", 0x1234), + buildcc::internal::Path("", 0x1234), }); CHECK_TRUE(pathstate == buildcc::internal::PathState::kRemoved); } @@ -101,13 +101,13 @@ TEST(TestBuilderInterfaceGroup, CheckPaths) { { auto pathstate = buildcc::internal::CheckPaths( { - buildcc::internal::Path::CreateNewPath("", 0x1234), - buildcc::internal::Path::CreateNewPath("v1", 0x2345), + buildcc::internal::Path("", 0x1234), + buildcc::internal::Path("v1", 0x2345), }, { - buildcc::internal::Path::CreateNewPath("", 0x1234), - buildcc::internal::Path::CreateNewPath("v1", 0x2345), - buildcc::internal::Path::CreateNewPath("v2", 0x3456), + buildcc::internal::Path("", 0x1234), + buildcc::internal::Path("v1", 0x2345), + buildcc::internal::Path("v2", 0x3456), }); CHECK_TRUE(pathstate == buildcc::internal::PathState::kAdded); } @@ -115,12 +115,12 @@ TEST(TestBuilderInterfaceGroup, CheckPaths) { { auto pathstate = buildcc::internal::CheckPaths( { - buildcc::internal::Path::CreateNewPath("", 0x1234), - buildcc::internal::Path::CreateNewPath("v1", 0x2345), + buildcc::internal::Path("", 0x1234), + buildcc::internal::Path("v1", 0x2345), }, { - buildcc::internal::Path::CreateNewPath("", 0x1234), - buildcc::internal::Path::CreateNewPath("v1", 0x3456), + buildcc::internal::Path("", 0x1234), + buildcc::internal::Path("v1", 0x3456), }); CHECK_TRUE(pathstate == buildcc::internal::PathState::kUpdated); } diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp index 0703046d..fdc0ba9c 100644 --- a/buildcc/lib/target/test/target/test_custom_generator.cpp +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -35,10 +35,10 @@ static bool BasicGenerateCb(const buildcc::CustomGeneratorContext &ctx) { TEST(CustomGeneratorTestGroup, Basic) { buildcc::CustomGenerator cgen("basic", ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - BasicGenerateCb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); cgen.Build(); mock().expectOneCall("BasicGenerateCb").andReturnValue(true); @@ -65,10 +65,10 @@ TEST(CustomGeneratorTestGroup, Basic) { TEST(CustomGeneratorTestGroup, Basic_Failure) { buildcc::CustomGenerator cgen("basic_failure", ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, {}, - BasicGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - BasicGenerateCb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, {}, + BasicGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); cgen.Build(); mock().expectOneCall("BasicGenerateCb").andReturnValue(true); @@ -88,11 +88,11 @@ TEST(CustomGeneratorTestGroup, Basic_Failure) { TEST(CustomGeneratorTestGroup, Basic_Group) { buildcc::CustomGenerator cgen("basic_group", ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - BasicGenerateCb); - cgen.AddGroup("grouped_id1_and_id2", {"id1", "id2"}); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.AddGroupInfo("grouped_id1_and_id2", {"id1", "id2"}); cgen.Build(); mock().expectOneCall("BasicGenerateCb").andReturnValue(true); @@ -119,11 +119,11 @@ TEST(CustomGeneratorTestGroup, Basic_Group) { TEST(CustomGeneratorTestGroup, Basic_Group_Dependency) { buildcc::CustomGenerator cgen("basic_group_dependency", ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - BasicGenerateCb); - cgen.AddGroup("grouped_id1_and_id2", {"id1", "id2"}, [](auto &&task_map) { + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.AddGroupInfo("grouped_id1_and_id2", {"id1", "id2"}, [](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); cgen.Build(); @@ -152,11 +152,11 @@ TEST(CustomGeneratorTestGroup, Basic_Group_Dependency) { TEST(CustomGeneratorTestGroup, Basic_Group_DependencyFailure) { buildcc::CustomGenerator cgen("basic_group_dependency_failure", ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - BasicGenerateCb); - cgen.AddGroup("grouped_id1_and_id2", {"id1", "id2"}, [](auto &&task_map) { + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.AddGroupInfo("grouped_id1_and_id2", {"id1", "id2"}, [](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); buildcc::env::assert_fatal("Failure"); }); @@ -190,10 +190,10 @@ bool SuccessCb(const buildcc::CustomGeneratorContext &ctx) { // ungrouped task TEST(CustomGeneratorTestGroup, Basic_Group_DependencyFailure2) { buildcc::CustomGenerator cgen("basic_group_dependency_failure2", ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FailureCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, SuccessCb); - cgen.AddGroup("grouped_id2", {"id2"}); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FailureCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, SuccessCb); + cgen.AddGroupInfo("grouped_id2", {"id2"}); cgen.AddDependencyCb([&](auto &&task_map) { task_map.at("id1").precede(task_map.at("grouped_id2")); }); @@ -261,10 +261,10 @@ TEST(CustomGeneratorTestGroup, Basic_ProperDependency_GoodCase) { rebuild_value = false; buildcc::CustomGenerator cgen("basic_proper_dependency_good_case", ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, ProperDependency1); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - ProperDependency2); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, ProperDependency1); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + ProperDependency2); cgen.AddDependencyCb( [](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); cgen.Build(); @@ -291,10 +291,10 @@ TEST(CustomGeneratorTestGroup, Basic_ProperDependency_BadCase) { rebuild_value = false; buildcc::CustomGenerator cgen("basic_proper_dependency_bad_case", ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, ProperDependency1); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - ProperDependency2); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, ProperDependency1); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + ProperDependency2); cgen.AddDependencyCb( [](auto &&task_map) { task_map.at("id2").precede(task_map.at("id1")); }); cgen.Build(); @@ -322,9 +322,9 @@ TEST(CustomGeneratorTestGroup, DefaultArgumentUsage) { {"dummy_main_o", "{current_build_dir}/dummy_main.o"}, {"dummy_main_cpp", "{current_root_dir}/dummy_main.cpp"}, }); - cgen.AddGenInfo("id1", {"{dummy_main_c}"}, {"{dummy_main_o}"}, - BasicGenerateCb); - cgen.AddGenInfo("id2", {"{dummy_main_cpp}"}, {}, BasicGenerateCb); + cgen.AddIdInfo("id1", {"{dummy_main_c}"}, {"{dummy_main_o}"}, + BasicGenerateCb); + cgen.AddIdInfo("id2", {"{dummy_main_cpp}"}, {}, BasicGenerateCb); cgen.Build(); mock().expectOneCall("BasicGenerateCb").andReturnValue(true); @@ -353,7 +353,7 @@ TEST(CustomGeneratorTestGroup, FailureCases) { { buildcc::CustomGenerator cgen("failure_no_cb", ""); buildcc::GenerateCb cb; - CHECK_THROWS(std::exception, cgen.AddGenInfo("id1", {}, {}, cb)); + CHECK_THROWS(std::exception, cgen.AddIdInfo("id1", {}, {}, cb)); } buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); @@ -363,8 +363,8 @@ TEST(CustomGeneratorTestGroup, FailureCases) { fs::create_directory( cgen.GetBinaryPath()); // make a folder so that file cannot be saved - cgen.AddGenInfo("id1", {}, {}, BasicGenerateCb); - cgen.AddGenInfo("id2", {}, {}, BasicGenerateCb); + cgen.AddIdInfo("id1", {}, {}, BasicGenerateCb); + cgen.AddIdInfo("id2", {}, {}, BasicGenerateCb); cgen.Build(); mock().expectOneCall("BasicGenerateCb").andReturnValue(true); @@ -390,7 +390,7 @@ TEST(CustomGeneratorTestGroup, FailureCases) { buildcc::env::set_task_state(buildcc::env::TaskState::FAILURE); buildcc::CustomGenerator cgen("gen_task_state_failure", ""); - cgen.AddGenInfo("id1", {}, {}, BasicGenerateCb); + cgen.AddIdInfo("id1", {}, {}, BasicGenerateCb); cgen.Build(); buildcc::m::CustomGeneratorRunner(cgen); @@ -421,10 +421,10 @@ TEST(CustomGeneratorTestGroup, AddDependency_BasicCheck) { constexpr const char *const kGenName = "add_dependency_basic_check"; { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, Dep2Cb); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, Dep1Cb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, Dep2Cb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, Dep1Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -461,10 +461,9 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep) { constexpr const char *const kGenName = "add_dependency_file_dep"; { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, - FileDep2Cb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -490,10 +489,9 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, - FileDep2Cb); + cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -512,10 +510,9 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { // Same, no change { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, - FileDep2Cb); + cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -537,8 +534,7 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { // sets dirty_ == true { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, - FileDep2Cb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -560,10 +556,9 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { // Added { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, - FileDep2Cb); + cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -592,10 +587,9 @@ TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, - FileDep2Cb); + cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); cgen.AddDependencyCb(DependencyCb); cgen.Build(); @@ -624,10 +618,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { constexpr const char *const kGenName = "real_generator_basic"; { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -646,10 +640,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, {}, - RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, {}, - RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, {}, + RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, {}, + RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -678,10 +672,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { constexpr const char *const kGenName = "real_generator_remove_and_add"; { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -705,10 +699,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { // Same, no change { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.Build(); buildcc::m::CustomGeneratorRunner(cgen); @@ -728,8 +722,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { // Map Removed { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.Build(); @@ -750,10 +744,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { // Map Added Failure { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.AddDependencyCb([](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); @@ -780,10 +774,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { // Map Added Success { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); cgen.Build(); buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); @@ -814,10 +808,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { buildcc::env::save_file( (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); - cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, - {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, + {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); cgen.AddDependencyCb([](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); @@ -850,10 +844,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { buildcc::env::save_file( (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); - cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, - {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, + {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); cgen.AddDependencyCb([](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); @@ -887,10 +881,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { buildcc::env::save_file( (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); - cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, - {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, + {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -925,10 +919,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { .time_since_epoch() .count()); - cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, - {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, + {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -946,9 +940,8 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); CHECK_EQUAL(imap.at("id2").outputs.size(), 1); - CHECK_EQUAL( - last_write_timestamp, - imap.at("id2").internal_inputs.begin()->GetLastWriteTimestamp()); + CHECK_EQUAL(last_write_timestamp, + imap.at("id2").internal_inputs.begin()->last_write_timestamp); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } @@ -958,11 +951,10 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddGenInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, - {"{current_build_dir}/rename_dummy_main.o"}, - RealGenerateCb); + cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); + cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, + {"{current_build_dir}/rename_dummy_main.o"}, RealGenerateCb); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -1019,9 +1011,9 @@ TEST(CustomGeneratorTestGroup, RealGenerate_BasicBlobRecheck) { constexpr const char *const kGenName = "real_generator_basic_blob_recheck"; { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb, - std::make_shared(12)); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb, + std::make_shared(12)); cgen.Build(); mock().expectOneCall("RealGenerateCb"); @@ -1037,9 +1029,9 @@ TEST(CustomGeneratorTestGroup, RealGenerate_BasicBlobRecheck) { // Rebuild { buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddGenInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb, - std::make_shared(200)); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, + {"{current_build_dir}/dummy_main.o"}, RealGenerateCb, + std::make_shared(200)); cgen.Build(); mock().expectOneCall("RealGenerateCb"); diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake index a2c8c710..aa48d13f 100644 --- a/buildcc/schema/cmake/schema.cmake +++ b/buildcc/schema/cmake/schema.cmake @@ -7,6 +7,7 @@ if (${TESTING}) include/schema/path.h src/custom_generator_serialization.cpp + include/schema/custom_generator_schema.h include/schema/custom_generator_serialization.h src/target_serialization.cpp diff --git a/buildcc/schema/include/schema/custom_generator_schema.h b/buildcc/schema/include/schema/custom_generator_schema.h new file mode 100644 index 00000000..a7058e3e --- /dev/null +++ b/buildcc/schema/include/schema/custom_generator_schema.h @@ -0,0 +1,82 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCHEMA_CUSTOM_GENERATOR_SCHEMA_H_ +#define SCHEMA_CUSTOM_GENERATOR_SCHEMA_H_ + +#include + +#include "schema/path.h" + +namespace buildcc::internal { + +struct CustomGeneratorSchema { +private: + static constexpr const char *const kSchemaName = "name"; + static constexpr const char *const kIdsName = "ids"; + static constexpr const char *const kGroupsName = "groups"; + +public: + using IdKey = std::string; + using GroupKey = std::string; + struct IdInfo { + private: + static constexpr const char *const kInputsName = "inputs"; + static constexpr const char *const kOutputsName = "outputs"; + static constexpr const char *const kUserblobName = "userblob"; + + public: + path_unordered_set internal_inputs; + fs_unordered_set outputs; + std::vector userblob; + + friend void to_json(json &j, const IdInfo &info) { + j[kInputsName] = info.internal_inputs; + j[kOutputsName] = info.outputs; + j[kUserblobName] = info.userblob; + } + + friend void from_json(const json &j, IdInfo &info) { + j.at(kInputsName).get_to(info.internal_inputs); + j.at(kOutputsName).get_to(info.outputs); + j.at(kUserblobName).get_to(info.userblob); + } + }; + + using IdPair = std::pair; + using GroupInfo = std::unordered_set; + using GroupPair = std::pair; + + std::string name; + std::unordered_map internal_ids; + std::unordered_map internal_groups; + + friend void to_json(json &j, const CustomGeneratorSchema &schema) { + j[kSchemaName] = schema.name; + j[kIdsName] = schema.internal_ids; + j[kGroupsName] = schema.internal_groups; + } + + friend void from_json(const json &j, CustomGeneratorSchema &schema) { + j.at(kSchemaName).get_to(schema.name); + j.at(kIdsName).get_to(schema.internal_ids); + j.at(kGroupsName).get_to(schema.internal_groups); + } +}; + +} // namespace buildcc::internal + +#endif diff --git a/buildcc/schema/include/schema/custom_generator_serialization.h b/buildcc/schema/include/schema/custom_generator_serialization.h index 13f66ba0..45b03a1f 100644 --- a/buildcc/schema/include/schema/custom_generator_serialization.h +++ b/buildcc/schema/include/schema/custom_generator_serialization.h @@ -21,69 +21,12 @@ #include #include -#include "schema/path.h" - #include "schema/interface/serialization_interface.h" -namespace buildcc::internal { - -struct CustomGeneratorSchema { -private: - static constexpr const char *const kSchemaName = "name"; - static constexpr const char *const kIdsName = "ids"; - static constexpr const char *const kGroupsName = "groups"; - -public: - using IdKey = std::string; - using GroupKey = std::string; - struct IdInfo { - private: - static constexpr const char *const kInputsName = "inputs"; - static constexpr const char *const kOutputsName = "outputs"; - static constexpr const char *const kUserblobName = "userblob"; - - public: - path_unordered_set internal_inputs; - fs_unordered_set outputs; - std::vector userblob; - - friend void to_json(json &j, const IdInfo &info) { - j = json{ - {kInputsName, info.internal_inputs}, - {kOutputsName, info.outputs}, - {kUserblobName, info.userblob}, - }; - } - - friend void from_json(const json &j, IdInfo &info) { - j.at(kInputsName).get_to(info.internal_inputs); - j.at(kOutputsName).get_to(info.outputs); - j.at(kUserblobName).get_to(info.userblob); - } - }; - - using IdPair = std::pair; - using GroupInfo = std::unordered_set; - using GroupPair = std::pair; - - std::string name; - std::unordered_map internal_ids; - std::unordered_map internal_groups; - - friend void to_json(json &j, const CustomGeneratorSchema &schema) { - j = json{ - {kSchemaName, schema.name}, - {kIdsName, schema.internal_ids}, - {kGroupsName, schema.internal_groups}, - }; - } +#include "schema/custom_generator_schema.h" +#include "schema/path.h" - friend void from_json(const json &j, CustomGeneratorSchema &schema) { - j.at(kSchemaName).get_to(schema.name); - j.at(kIdsName).get_to(schema.internal_ids); - j.at(kGroupsName).get_to(schema.internal_groups); - } -}; +namespace buildcc::internal { class CustomGeneratorSerialization : public SerializationInterface { public: diff --git a/buildcc/schema/include/schema/path.h b/buildcc/schema/include/schema/path.h index 12406600..755fa6db 100644 --- a/buildcc/schema/include/schema/path.h +++ b/buildcc/schema/include/schema/path.h @@ -34,16 +34,16 @@ using json = nlohmann::ordered_json; namespace buildcc::internal { -class Path { +struct Path { private: static constexpr const char *const kPathName = "path"; static constexpr const char *const kHashName = "hash"; public: Path() = default; - explicit Path(const fs::path &pathname, std::uint64_t last_write_timestamp) - : pathname_(pathname), last_write_timestamp_(last_write_timestamp) { - pathname_.lexically_normal().make_preferred(); + Path(const fs::path &path, std::uint64_t timestamp = 0) + : pathname(path), last_write_timestamp(timestamp) { + pathname.lexically_normal().make_preferred(); } /** @@ -66,27 +66,6 @@ class Path { return Path(pathname, last_write_timestamp); } - static Path CreateNewPath(const fs::path &pathname, - uint64_t last_write_timestamp) noexcept { - return Path(pathname, last_write_timestamp); - } - - /** - * @brief Create a New Path object and sets last_write_timestamp to 0 - * - * @param pathname - * @return Path - */ - static Path CreateNewPath(const fs::path &pathname) { - return Path(pathname, 0); - } - - // Getters - std::uint64_t GetLastWriteTimestamp() const noexcept { - return last_write_timestamp_; - } - const fs::path &GetPathname() const noexcept { return pathname_; } - /** * @brief Get fs::path as std::string while keeping the preferred os * path delimiters @@ -94,7 +73,7 @@ class Path { * * @return std::string */ - std::string GetPathAsString() const { return GetPathname().string(); } + std::string GetPathAsString() const { return pathname.string(); } /** * @brief Get fs::path as std::string for display @@ -107,26 +86,22 @@ class Path { } // Used during find operation - bool operator==(const Path &p) const { - return GetPathname() == p.GetPathname(); - } + bool operator==(const Path &p) const { return pathname == p.pathname; } - bool operator==(const fs::path &pathname) const { - return GetPathname() == pathname; + bool operator==(const fs::path &other_pathname) const { + return pathname == other_pathname; } // JSON specialization friend void to_json(json &j, const Path &p) { - j = json{ - {kPathName, p.pathname_}, - {kHashName, p.last_write_timestamp_}, - }; + j[kPathName] = p.pathname; + j[kHashName] = p.last_write_timestamp; } friend void from_json(const json &j, Path &p) { - j.at(kPathName).get_to(p.pathname_); - j.at(kHashName).get_to(p.last_write_timestamp_); + j.at(kPathName).get_to(p.pathname); + j.at(kHashName).get_to(p.last_write_timestamp); } private: @@ -138,22 +113,21 @@ class Path { } std::string ConvertPathToString() const { - std::string pstr = pathname_.string(); + std::string pstr = pathname.string(); std::replace(pstr.begin(), pstr.end(), '\\', '/'); return pstr; } -private: - fs::path pathname_; - std::uint64_t last_write_timestamp_; +public: + fs::path pathname; + // TODO, Change this to std::string hash + std::uint64_t last_write_timestamp{0}; }; // Used by Path class PathHash { public: - size_t operator()(const Path &p) const { - return fs::hash_value(p.GetPathname()); - } + size_t operator()(const Path &p) const { return fs::hash_value(p.pathname); } size_t operator()(const fs::path &p) const { return fs::hash_value(p); } }; @@ -187,7 +161,7 @@ inline fs_unordered_set path_schema_convert(const path_unordered_set &internal_path_set) { fs_unordered_set path_set; for (const auto &p : internal_path_set) { - path_set.insert(p.GetPathname()); + path_set.insert(p.pathname); } return path_set; } @@ -197,15 +171,15 @@ path_schema_convert(const path_unordered_set &internal_path_set) { namespace buildcc { inline std::string path_as_string(const fs::path &p) { - return internal::Path::CreateNewPath(p).GetPathAsString(); + return internal::Path(p).GetPathAsString(); } inline std::string path_as_display_string(const fs::path &p) { - return internal::Path::CreateNewPath(p).GetPathAsStringForDisplay(); + return internal::Path(p).GetPathAsStringForDisplay(); } inline fs::path string_as_path(const std::string &str) { - return internal::Path::CreateNewPath(str).GetPathname(); + return internal::Path(str).pathname; } using fs_unordered_set = internal::fs_unordered_set; diff --git a/buildcc/schema/include/schema/private/schema_util.h b/buildcc/schema/include/schema/private/schema_util.h index d69263fe..3a826016 100644 --- a/buildcc/schema/include/schema/private/schema_util.h +++ b/buildcc/schema/include/schema/private/schema_util.h @@ -38,8 +38,7 @@ inline void extract_path( } for (auto iter = fbs_paths->begin(); iter != fbs_paths->end(); iter++) { - out.insert(Path::CreateNewPath(iter->pathname()->c_str(), - iter->last_write_timestamp())); + out.insert(Path(iter->pathname()->c_str(), iter->last_write_timestamp())); } } @@ -52,8 +51,8 @@ inline void extract_path( } for (auto iter = fbs_paths->begin(); iter != fbs_paths->end(); iter++) { - out.push_back(Path::CreateNewPath(iter->pathname()->c_str(), - iter->last_write_timestamp())); + out.push_back( + Path(iter->pathname()->c_str(), iter->last_write_timestamp())); } } @@ -118,7 +117,7 @@ create_fbs_vector_path(flatbuffers::FlatBufferBuilder &builder, std::vector> paths; for (const auto &p : pathlist) { auto fbs_file = fbs::CreatePathDirect(builder, p.GetPathAsString().c_str(), - p.GetLastWriteTimestamp()); + p.last_write_timestamp); paths.push_back(fbs_file); } return paths; diff --git a/buildcc/schema/src/custom_generator_serialization.cpp b/buildcc/schema/src/custom_generator_serialization.cpp index 8cc22aa6..e71d0097 100644 --- a/buildcc/schema/src/custom_generator_serialization.cpp +++ b/buildcc/schema/src/custom_generator_serialization.cpp @@ -29,15 +29,18 @@ bool CustomGeneratorSerialization::Verify(const std::string &serialized_data) { } bool CustomGeneratorSerialization::Load(const std::string &serialized_data) { - bool is_loaded = true; - try { - json j = json::parse(serialized_data, nullptr, true, true); - load_ = j.get(); - } catch (const std::exception &e) { - env::log_critical(__FUNCTION__, e.what()); - is_loaded = false; + json j = json::parse(serialized_data, nullptr, false); + bool loaded = !j.is_discarded(); + + if (loaded) { + try { + load_ = j.get(); + } catch (const std::exception &e) { + env::log_critical(__FUNCTION__, e.what()); + loaded = false; + } } - return is_loaded; + return loaded; } bool CustomGeneratorSerialization::Store( diff --git a/buildcc/schema/test/test_custom_generator_serialization.cpp b/buildcc/schema/test/test_custom_generator_serialization.cpp index e92f69d3..3c215257 100644 --- a/buildcc/schema/test/test_custom_generator_serialization.cpp +++ b/buildcc/schema/test/test_custom_generator_serialization.cpp @@ -20,6 +20,31 @@ TEST_GROUP(CustomGeneratorSerializationTestGroup) }; // clang-format on +TEST(CustomGeneratorSerializationTestGroup, JsonParse_Failure) { + { + // JSON Parse fails + buildcc::internal::CustomGeneratorSerialization serialization( + "dump/JsonParseFailure.json"); + + buildcc::env::save_file(serialization.GetSerializedFile().string().c_str(), + std::string(""), false); + bool loaded = serialization.LoadFromFile(); + CHECK_FALSE(loaded); + } + + { + // Custom Generator Schema conversion fails + buildcc::internal::CustomGeneratorSerialization serialization( + "dump/JsonParseFailure.json"); + + auto data = R"({"name": ""})"; + buildcc::env::save_file(serialization.GetSerializedFile().string().c_str(), + data, false); + bool loaded = serialization.LoadFromFile(); + CHECK_FALSE(loaded); + } +} + TEST(CustomGeneratorSerializationTestGroup, FormatEmptyCheck) { buildcc::internal::CustomGeneratorSerialization serialization( "dump/FormatEmptyCheck.json"); diff --git a/cmake/coverage/lcov.cmake b/cmake/coverage/lcov.cmake index e658e4bb..f7551a9b 100644 --- a/cmake/coverage/lcov.cmake +++ b/cmake/coverage/lcov.cmake @@ -16,6 +16,7 @@ else() ) set(LCOV_REMOVE_OPTIONS "/usr*" + "*third_party*" "*/CppUTestExt*" "*/CppUTest*" "*/fmt*" From 2c2337e6d453d6f90dcbdc0b75e40c4894e35cae Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 5 Nov 2022 16:01:10 -0700 Subject: [PATCH 30/35] [Serialization] JSON Serialization for Target (#225) --- bootstrap/include/bootstrap/build_buildcc.h | 11 +- bootstrap/src/build_buildcc.cpp | 46 +--- buildcc/schema/CMakeLists.txt | 1 - buildcc/schema/cmake/schema.cmake | 16 +- buildcc/schema/cmake/schema_generate.cmake | 24 --- .../include/schema/custom_generator_schema.h | 36 ++-- .../include/schema/private/schema_util.h | 153 -------------- buildcc/schema/include/schema/target_schema.h | 142 +++++++++++++ .../include/schema/target_serialization.h | 31 +-- buildcc/schema/include/schema/target_type.h | 35 ++++ buildcc/schema/path.fbs | 20 -- buildcc/schema/src/target_serialization.cpp | 118 ++--------- buildcc/schema/target.fbs | 67 ------ .../test_custom_generator_serialization.cpp | 14 +- .../schema/test/test_target_serialization.cpp | 196 ++++++++++++++++++ 15 files changed, 432 insertions(+), 478 deletions(-) delete mode 100644 buildcc/schema/cmake/schema_generate.cmake delete mode 100644 buildcc/schema/include/schema/private/schema_util.h create mode 100644 buildcc/schema/include/schema/target_schema.h delete mode 100644 buildcc/schema/path.fbs delete mode 100644 buildcc/schema/target.fbs create mode 100644 buildcc/schema/test/test_target_serialization.cpp diff --git a/bootstrap/include/bootstrap/build_buildcc.h b/bootstrap/include/bootstrap/build_buildcc.h index e8fb8110..da4cc9f1 100644 --- a/bootstrap/include/bootstrap/build_buildcc.h +++ b/bootstrap/include/bootstrap/build_buildcc.h @@ -30,10 +30,7 @@ namespace buildcc { -void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe); - -void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, - const TargetInfo &flatbuffers_ho, +void buildcc_cb(BaseTarget &target, const TargetInfo &flatbuffers_ho, const TargetInfo &nlohmann_json_ho, const TargetInfo &fmt_ho, const TargetInfo &spdlog_ho, const TargetInfo &cli11_ho, const TargetInfo &taskflow_ho, const TargetInfo &tl_optional_ho, @@ -57,9 +54,6 @@ class BuildBuildCC { // Executable static constexpr const char *const kFlatcExeName = "flatc"; - // Generator - static constexpr const char *const kSchemaGenName = "schema_gen"; - // Libraries static constexpr const char *const kTplLibName = "libtpl"; static constexpr const char *const kBuildccLibName = "libbuildcc"; @@ -86,9 +80,6 @@ class BuildBuildCC { ExecutableTarget_generic &GetFlatc() { return storage_.Ref(kFlatcExeName); } - FileGenerator &GetSchemaGen() { - return storage_.Ref(kSchemaGenName); - } TargetInfo &GetFlatbuffersHo() { return storage_.Ref(kFlatbuffersHoName); } diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index 8e72841d..662e0728 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -18,37 +18,13 @@ namespace buildcc { -void schema_gen_cb(FileGenerator &generator, const BaseTarget &flatc_exe) { - generator.AddPattern("path_fbs", "{current_root_dir}/path.fbs"); - generator.AddPattern("target_fbs", "{current_root_dir}/target.fbs"); - - generator.AddInput("{path_fbs}"); - generator.AddInput("{target_fbs}"); - - generator.AddOutput("{current_build_dir}/path_generated.h"); - generator.AddOutput("{current_build_dir}/target_generated.h"); - - generator.AddPatterns({ - {"flatc_compiler", fmt::format("{}", flatc_exe.GetTargetPath())}, - }); - // generator.AddCommand("{flatc_compiler} --help"); - generator.AddCommand("{flatc_compiler} -o {current_build_dir} -I " - "{current_root_dir} --gen-object-api " - "--cpp {path_fbs} {target_fbs}"); - - generator.Build(); -} - -void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, - const TargetInfo &flatbuffers_ho, +void buildcc_cb(BaseTarget &target, const TargetInfo &flatbuffers_ho, const TargetInfo &nlohmann_json_ho, const TargetInfo &fmt_ho, const TargetInfo &spdlog_ho, const TargetInfo &cli11_ho, const TargetInfo &taskflow_ho, const TargetInfo &tl_optional_ho, const BaseTarget &tpl) { // NOTE, Build as single lib target.AddIncludeDir("", true); - const std::string &schema_build_dir = schema_gen.Get("current_build_dir"); - target.AddIncludeDirAbsolute(schema_build_dir, true); // ENV target.GlobSources("lib/env/src"); @@ -60,7 +36,6 @@ void buildcc_cb(BaseTarget &target, const FileGenerator &schema_gen, target.AddIncludeDir("schema/include"); target.GlobHeaders("schema/include/schema"); target.GlobHeaders("schema/include/schema/interface"); - target.GlobHeaders("schema/include/schema/private"); // TOOLCHAIN target.GlobSources("lib/toolchain/src/api"); @@ -205,12 +180,6 @@ void BuildBuildCC::Initialize() { TargetEnv(env_.GetTargetRootDir() / "third_party" / "flatbuffers", env_.GetTargetBuildDir())); - // Schema - (void)storage_.Add( - kSchemaGenName, kSchemaGenName, - TargetEnv(env_.GetTargetRootDir() / "buildcc" / "schema", - env_.GetTargetBuildDir() / toolchain_.GetName())); - // Flatbuffers HO lib (void)storage_.Add( kFlatbuffersHoName, toolchain_, @@ -271,8 +240,6 @@ void BuildBuildCC::Initialize() { } void BuildBuildCC::Setup(const ArgToolchainState &state) { - auto &flatc_exe = GetFlatc(); - auto &schema_gen = GetSchemaGen(); auto &flatbuffers_ho_lib = GetFlatbuffersHo(); auto &nlohmann_json_ho_lib = GetNlohmannJsonHo(); auto &cli11_ho_lib = GetCli11Ho(); @@ -283,10 +250,6 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { auto &tpl_lib = GetTpl(); auto &buildcc_lib = GetBuildcc(); Reg::Toolchain(state) - .Func(global_flags_cb, flatc_exe, toolchain_) - .Build(build_flatc_exe_cb, flatc_exe) - .Build(schema_gen_cb, schema_gen, flatc_exe) - .Dep(schema_gen, flatc_exe) .Func(flatbuffers_ho_cb, flatbuffers_ho_lib) .Func(nlohmann_json_ho_cb, nlohmann_json_ho_lib) .Func(cli11_ho_cb, cli11_ho_lib) @@ -297,10 +260,9 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { .Func(global_flags_cb, tpl_lib, toolchain_) .Build(tpl_cb, tpl_lib) .Func(global_flags_cb, buildcc_lib, toolchain_) - .Build(buildcc_cb, buildcc_lib, schema_gen, flatbuffers_ho_lib, - nlohmann_json_ho_lib, fmt_ho_lib, spdlog_ho_lib, cli11_ho_lib, - taskflow_ho_lib, tl_optional_ho_lib, tpl_lib) - .Dep(buildcc_lib, schema_gen) + .Build(buildcc_cb, buildcc_lib, flatbuffers_ho_lib, nlohmann_json_ho_lib, + fmt_ho_lib, spdlog_ho_lib, cli11_ho_lib, taskflow_ho_lib, + tl_optional_ho_lib, tpl_lib) .Dep(buildcc_lib, tpl_lib); } diff --git a/buildcc/schema/CMakeLists.txt b/buildcc/schema/CMakeLists.txt index 6883e1a5..2f953e53 100644 --- a/buildcc/schema/CMakeLists.txt +++ b/buildcc/schema/CMakeLists.txt @@ -1,2 +1 @@ -include(cmake/schema_generate.cmake) include(cmake/schema.cmake) diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake index aa48d13f..20ba85cf 100644 --- a/buildcc/schema/cmake/schema.cmake +++ b/buildcc/schema/cmake/schema.cmake @@ -1,7 +1,6 @@ # schema test if (${TESTING}) add_library(mock_schema STATIC - include/schema/private/schema_util.h include/schema/interface/serialization_interface.h include/schema/path.h @@ -11,6 +10,7 @@ if (${TESTING}) include/schema/custom_generator_serialization.h src/target_serialization.cpp + include/schema/target_schema.h include/schema/target_serialization.h ) target_include_directories(mock_schema PUBLIC @@ -27,7 +27,6 @@ if (${TESTING}) CppUTestExt ${TEST_LINK_LIBS} ) - add_dependencies(mock_schema fbs_to_header) target_compile_options(mock_schema PUBLIC ${TEST_COMPILE_FLAGS} ${BUILD_COMPILE_FLAGS}) target_link_options(mock_schema PUBLIC ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS}) @@ -38,21 +37,30 @@ if (${TESTING}) ) target_link_libraries(test_custom_generator_serialization PRIVATE mock_schema) + add_executable(test_target_serialization + test/test_target_serialization.cpp + ) + target_link_libraries(test_target_serialization PRIVATE mock_schema) + add_test(NAME test_custom_generator_serialization COMMAND test_custom_generator_serialization WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test ) + add_test(NAME test_target_serialization COMMAND test_target_serialization + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test + ) endif() set(SCHEMA_SRCS - include/schema/private/schema_util.h include/schema/interface/serialization_interface.h include/schema/path.h src/custom_generator_serialization.cpp + include/schema/custom_generator_schema.h include/schema/custom_generator_serialization.h src/target_serialization.cpp + include/schema/target_schema.h include/schema/target_serialization.h ) @@ -67,7 +75,6 @@ if(${BUILDCC_BUILD_AS_SINGLE_LIB}) target_include_directories(buildcc PRIVATE ${SCHEMA_BUILD_DIR} ) - add_dependencies(buildcc fbs_to_header) endif() if(${BUILDCC_BUILD_AS_INTERFACE}) @@ -89,7 +96,6 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) ) target_compile_options(schema PRIVATE ${BUILD_COMPILE_FLAGS}) target_link_options(schema PRIVATE ${BUILD_LINK_FLAGS}) - add_dependencies(schema fbs_to_header) endif() if (${BUILDCC_INSTALL}) diff --git a/buildcc/schema/cmake/schema_generate.cmake b/buildcc/schema/cmake/schema_generate.cmake deleted file mode 100644 index c1a6b604..00000000 --- a/buildcc/schema/cmake/schema_generate.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# Generate files -set(SCHEMA_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated CACHE PATH "Generate path of flatbuffer schema") - -set(FBS_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/path.fbs - ${CMAKE_CURRENT_SOURCE_DIR}/target.fbs -) -set(FBS_GEN_FILES - ${SCHEMA_BUILD_DIR}/path_generated.h - ${SCHEMA_BUILD_DIR}/target_generated.h -) -set(FBS_GEN_OPTIONS - -I ${CMAKE_CURRENT_SOURCE_DIR} - --gen-object-api -) - -add_custom_command(OUTPUT ${FBS_GEN_FILES} - COMMAND flatc -o ${SCHEMA_BUILD_DIR} ${FBS_GEN_OPTIONS} --cpp ${FBS_FILES} - DEPENDS flatc ${FBS_FILES} -) - -add_custom_target(fbs_to_header - DEPENDS ${FBS_GEN_FILES} -) diff --git a/buildcc/schema/include/schema/custom_generator_schema.h b/buildcc/schema/include/schema/custom_generator_schema.h index a7058e3e..0a171f2c 100644 --- a/buildcc/schema/include/schema/custom_generator_schema.h +++ b/buildcc/schema/include/schema/custom_generator_schema.h @@ -25,18 +25,18 @@ namespace buildcc::internal { struct CustomGeneratorSchema { private: - static constexpr const char *const kSchemaName = "name"; - static constexpr const char *const kIdsName = "ids"; - static constexpr const char *const kGroupsName = "groups"; + static constexpr const char *const kName = "name"; + static constexpr const char *const kIds = "ids"; + static constexpr const char *const kGroups = "groups"; public: using IdKey = std::string; using GroupKey = std::string; struct IdInfo { private: - static constexpr const char *const kInputsName = "inputs"; - static constexpr const char *const kOutputsName = "outputs"; - static constexpr const char *const kUserblobName = "userblob"; + static constexpr const char *const kInputs = "inputs"; + static constexpr const char *const kOutputs = "outputs"; + static constexpr const char *const kUserblob = "userblob"; public: path_unordered_set internal_inputs; @@ -44,15 +44,15 @@ struct CustomGeneratorSchema { std::vector userblob; friend void to_json(json &j, const IdInfo &info) { - j[kInputsName] = info.internal_inputs; - j[kOutputsName] = info.outputs; - j[kUserblobName] = info.userblob; + j[kInputs] = info.internal_inputs; + j[kOutputs] = info.outputs; + j[kUserblob] = info.userblob; } friend void from_json(const json &j, IdInfo &info) { - j.at(kInputsName).get_to(info.internal_inputs); - j.at(kOutputsName).get_to(info.outputs); - j.at(kUserblobName).get_to(info.userblob); + j.at(kInputs).get_to(info.internal_inputs); + j.at(kOutputs).get_to(info.outputs); + j.at(kUserblob).get_to(info.userblob); } }; @@ -65,15 +65,15 @@ struct CustomGeneratorSchema { std::unordered_map internal_groups; friend void to_json(json &j, const CustomGeneratorSchema &schema) { - j[kSchemaName] = schema.name; - j[kIdsName] = schema.internal_ids; - j[kGroupsName] = schema.internal_groups; + j[kName] = schema.name; + j[kIds] = schema.internal_ids; + j[kGroups] = schema.internal_groups; } friend void from_json(const json &j, CustomGeneratorSchema &schema) { - j.at(kSchemaName).get_to(schema.name); - j.at(kIdsName).get_to(schema.internal_ids); - j.at(kGroupsName).get_to(schema.internal_groups); + j.at(kName).get_to(schema.name); + j.at(kIds).get_to(schema.internal_ids); + j.at(kGroups).get_to(schema.internal_groups); } }; diff --git a/buildcc/schema/include/schema/private/schema_util.h b/buildcc/schema/include/schema/private/schema_util.h deleted file mode 100644 index 3a826016..00000000 --- a/buildcc/schema/include/schema/private/schema_util.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SCHEMA_PRIVATE_SCHEMA_UTIL_H_ -#define SCHEMA_PRIVATE_SCHEMA_UTIL_H_ - -#include "path_generated.h" - -#include - -#include "schema/path.h" - -namespace fbs = schema::internal; - -namespace buildcc::internal { - -// extract APIs for LOAD - -inline void extract_path( - const flatbuffers::Vector> - *fbs_paths, - path_unordered_set &out) { - if (fbs_paths == nullptr) { - return; - } - - for (auto iter = fbs_paths->begin(); iter != fbs_paths->end(); iter++) { - out.insert(Path(iter->pathname()->c_str(), iter->last_write_timestamp())); - } -} - -inline void extract_path( - const flatbuffers::Vector> - *fbs_paths, - std::vector &out) { - if (fbs_paths == nullptr) { - return; - } - - for (auto iter = fbs_paths->begin(); iter != fbs_paths->end(); iter++) { - out.push_back( - Path(iter->pathname()->c_str(), iter->last_write_timestamp())); - } -} - -inline void extract(const flatbuffers::Vector *fbs_data, - std::vector &out) { - if (fbs_data == nullptr) { - return; - } - - for (auto iter = fbs_data->begin(); iter != fbs_data->end(); iter++) { - out.push_back(*iter); - } -} - -inline void -extract(const flatbuffers::Vector> - *fbs_paths, - fs_unordered_set &out) { - if (fbs_paths == nullptr) { - return; - } - - for (auto iter = fbs_paths->begin(); iter != fbs_paths->end(); iter++) { - out.insert(iter->str()); - } -} - -template -inline void -extract(const flatbuffers::Vector> - *fbs_paths, - std::unordered_set &out) { - if (fbs_paths == nullptr) { - return; - } - - for (auto iter = fbs_paths->begin(); iter != fbs_paths->end(); iter++) { - out.insert(iter->str()); - } -} - -template -inline void -extract(const flatbuffers::Vector> - *fbs_paths, - std::vector &out) { - if (fbs_paths == nullptr) { - return; - } - - for (auto iter = fbs_paths->begin(); iter != fbs_paths->end(); iter++) { - out.push_back(iter->str()); - } -} - -// Create APIs for STORE - -template -inline std::vector> -create_fbs_vector_path(flatbuffers::FlatBufferBuilder &builder, - const T &pathlist) { - std::vector> paths; - for (const auto &p : pathlist) { - auto fbs_file = fbs::CreatePathDirect(builder, p.GetPathAsString().c_str(), - p.last_write_timestamp); - paths.push_back(fbs_file); - } - return paths; -} - -template -inline std::vector> -create_fbs_vector_string(flatbuffers::FlatBufferBuilder &builder, - const T &strlist) { - std::vector> strs; - std::transform( - strlist.begin(), strlist.end(), std::back_inserter(strs), - [&](const std::string &str) -> flatbuffers::Offset { - return builder.CreateString(str); - }); - return strs; -} - -inline std::vector> -create_fbs_vector_string(flatbuffers::FlatBufferBuilder &builder, - const buildcc::fs_unordered_set &fslist) { - std::vector> strs; - std::transform( - fslist.begin(), fslist.end(), std::back_inserter(strs), - [&](const fs::path &p) -> flatbuffers::Offset { - return builder.CreateString(path_as_string(p)); - }); - return strs; -} - -} // namespace buildcc::internal - -#endif diff --git a/buildcc/schema/include/schema/target_schema.h b/buildcc/schema/include/schema/target_schema.h new file mode 100644 index 00000000..f1cae3f0 --- /dev/null +++ b/buildcc/schema/include/schema/target_schema.h @@ -0,0 +1,142 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCHEMA_TARGET_SCHEMA_H_ +#define SCHEMA_TARGET_SCHEMA_H_ + +#include +#include + +#include "schema/path.h" +#include "schema/target_type.h" + +namespace buildcc::internal { + +struct TargetSchema { + std::string name; + TargetType type{TargetType::Undefined}; + + path_unordered_set internal_sources; + path_unordered_set internal_headers; + path_unordered_set internal_pchs; + std::vector internal_libs; + std::vector external_libs; + + fs_unordered_set include_dirs; + fs_unordered_set lib_dirs; + + std::unordered_set preprocessor_flags; + std::unordered_set common_compile_flags; + std::unordered_set pch_compile_flags; + std::unordered_set pch_object_flags; + std::unordered_set asm_compile_flags; + std::unordered_set c_compile_flags; + std::unordered_set cpp_compile_flags; + std::unordered_set link_flags; + + path_unordered_set internal_compile_dependencies; + path_unordered_set internal_link_dependencies; + + bool pch_compiled{false}; + bool target_linked{false}; + +private: + static constexpr const char *const kName = "name"; + static constexpr const char *const kType = "type"; + + static constexpr const char *const kSources = "sources"; + static constexpr const char *const kHeaders = "headers"; + static constexpr const char *const kPchs = "pchs"; + static constexpr const char *const kLibs = "libs"; + static constexpr const char *const kExternalLibs = "external_libs"; + + static constexpr const char *const kIncludeDirs = "include_dirs"; + static constexpr const char *const kLibDirs = "lib_dirs"; + + static constexpr const char *const kPreprocessorFlags = "preprocessor_flags"; + static constexpr const char *const kCommonCompileFlags = + "common_compile_flags"; + static constexpr const char *const kPchCompileFlags = "pch_compile_flags"; + static constexpr const char *const kPchObjectFlags = "pch_object_flags"; + static constexpr const char *const kAsmCompileFlags = "asm_compile_flags"; + static constexpr const char *const kCCompileFlags = "c_compile_flags"; + static constexpr const char *const kCppCompileFlags = "cpp_compile_flags"; + static constexpr const char *const kLinkFlags = "link_flags"; + + static constexpr const char *const kCompileDependencies = + "compile_dependencies"; + static constexpr const char *const kLinkDependencies = "link_dependencies"; + + static constexpr const char *const kPchCompiled = "pch_compiled"; + static constexpr const char *const kTargetLinked = "target_linked"; + +public: + friend void to_json(json &j, const TargetSchema &schema) { + j[kName] = schema.name; + j[kType] = schema.type; + j[kSources] = schema.internal_sources; + j[kHeaders] = schema.internal_headers; + j[kPchs] = schema.internal_pchs; + j[kLibs] = schema.internal_libs; + j[kExternalLibs] = schema.external_libs; + j[kIncludeDirs] = schema.include_dirs; + j[kLibDirs] = schema.lib_dirs; + + j[kPreprocessorFlags] = schema.preprocessor_flags; + j[kCommonCompileFlags] = schema.common_compile_flags; + j[kPchCompileFlags] = schema.pch_compile_flags; + j[kPchObjectFlags] = schema.pch_object_flags; + j[kAsmCompileFlags] = schema.asm_compile_flags; + j[kCCompileFlags] = schema.c_compile_flags; + j[kCppCompileFlags] = schema.cpp_compile_flags; + j[kLinkFlags] = schema.link_flags; + + j[kCompileDependencies] = schema.internal_compile_dependencies; + j[kLinkDependencies] = schema.internal_link_dependencies; + j[kPchCompiled] = schema.pch_compiled; + j[kTargetLinked] = schema.target_linked; + } + + friend void from_json(const json &j, TargetSchema &schema) { + j.at(kName).get_to(schema.name); + j.at(kType).get_to(schema.type); + j.at(kSources).get_to(schema.internal_sources); + j.at(kHeaders).get_to(schema.internal_headers); + j.at(kPchs).get_to(schema.internal_pchs); + j.at(kLibs).get_to(schema.internal_libs); + j.at(kExternalLibs).get_to(schema.external_libs); + j.at(kIncludeDirs).get_to(schema.include_dirs); + j.at(kLibDirs).get_to(schema.lib_dirs); + + j.at(kPreprocessorFlags).get_to(schema.preprocessor_flags); + j.at(kCommonCompileFlags).get_to(schema.common_compile_flags); + j.at(kPchCompileFlags).get_to(schema.pch_compile_flags); + j.at(kPchObjectFlags).get_to(schema.pch_object_flags); + j.at(kAsmCompileFlags).get_to(schema.asm_compile_flags); + j.at(kCCompileFlags).get_to(schema.c_compile_flags); + j.at(kCppCompileFlags).get_to(schema.cpp_compile_flags); + j.at(kLinkFlags).get_to(schema.link_flags); + + j.at(kCompileDependencies).get_to(schema.internal_compile_dependencies); + j.at(kLinkDependencies).get_to(schema.internal_link_dependencies); + j.at(kPchCompiled).get_to(schema.pch_compiled); + j.at(kTargetLinked).get_to(schema.target_linked); + } +}; + +} // namespace buildcc::internal + +#endif diff --git a/buildcc/schema/include/schema/target_serialization.h b/buildcc/schema/include/schema/target_serialization.h index e4869f3b..bc5116a3 100644 --- a/buildcc/schema/include/schema/target_serialization.h +++ b/buildcc/schema/include/schema/target_serialization.h @@ -20,41 +20,12 @@ #include #include "schema/path.h" -#include "schema/target_type.h" +#include "schema/target_schema.h" #include "schema/interface/serialization_interface.h" namespace buildcc::internal { -struct TargetSchema { - std::string name; - TargetType type{TargetType::Undefined}; - - path_unordered_set internal_sources; - path_unordered_set internal_headers; - path_unordered_set internal_pchs; - std::vector internal_libs; - std::vector external_libs; - - fs_unordered_set include_dirs; - fs_unordered_set lib_dirs; - - std::unordered_set preprocessor_flags; - std::unordered_set common_compile_flags; - std::unordered_set pch_compile_flags; - std::unordered_set pch_object_flags; - std::unordered_set asm_compile_flags; - std::unordered_set c_compile_flags; - std::unordered_set cpp_compile_flags; - std::unordered_set link_flags; - - path_unordered_set internal_compile_dependencies; - path_unordered_set internal_link_dependencies; - - bool pch_compiled{false}; - bool target_linked{false}; -}; - class TargetSerialization : public SerializationInterface { public: TargetSerialization(const fs::path &serialized_file) diff --git a/buildcc/schema/include/schema/target_type.h b/buildcc/schema/include/schema/target_type.h index 866b030b..2871551a 100644 --- a/buildcc/schema/include/schema/target_type.h +++ b/buildcc/schema/include/schema/target_type.h @@ -17,6 +17,10 @@ #ifndef SCHEMA_TARGET_TYPE_H_ #define SCHEMA_TARGET_TYPE_H_ +#include +#include +#include + namespace buildcc { enum class TargetType { @@ -26,6 +30,37 @@ enum class TargetType { Undefined, ///< Undefined target type }; +constexpr std::array, 3> + kTargetTypeInfo{ + std::make_pair("executable", TargetType::Executable), + std::make_pair("static_library", TargetType::StaticLibrary), + std::make_pair("dynamic_library", TargetType::DynamicLibrary), + }; + +template void to_json(JsonType &j, TargetType type) { + j = nullptr; + auto iter = std::find_if(kTargetTypeInfo.cbegin(), kTargetTypeInfo.cend(), + [type](const auto &p) { return p.second == type; }); + if (iter != kTargetTypeInfo.cend()) { + j = iter->first; + } } +template +void from_json(const JsonType &j, TargetType &type) { + type = TargetType::Undefined; + if (j.is_string()) { + std::string name; + j.get_to(name); + auto iter = + std::find_if(kTargetTypeInfo.cbegin(), kTargetTypeInfo.cend(), + [&name](const auto &p) { return p.first == name; }); + if (iter != kTargetTypeInfo.cend()) { + type = iter->second; + } + } +} + +} // namespace buildcc + #endif diff --git a/buildcc/schema/path.fbs b/buildcc/schema/path.fbs deleted file mode 100644 index 3407649e..00000000 --- a/buildcc/schema/path.fbs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2021-2022 Niket Naidu. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -namespace schema.internal; - -table Path { - pathname:string (key); - last_write_timestamp:uint64; -} diff --git a/buildcc/schema/src/target_serialization.cpp b/buildcc/schema/src/target_serialization.cpp index 68fdaa24..9e447893 100644 --- a/buildcc/schema/src/target_serialization.cpp +++ b/buildcc/schema/src/target_serialization.cpp @@ -16,15 +16,6 @@ #include "schema/target_serialization.h" -// Third party -#include "flatbuffers/flatbuffers.h" - -// Private -#include "schema/private/schema_util.h" - -// Schema generated -#include "target_generated.h" - namespace buildcc::internal { // PUBLIC @@ -32,8 +23,9 @@ void TargetSerialization::UpdatePchCompiled(const TargetSchema &store) { store_.internal_pchs = store.internal_pchs; store_.pch_compiled = true; } + void TargetSerialization::AddSource(const internal::Path &source) { - std::lock_guard guard(add_source_mutex); + std::scoped_lock guard(add_source_mutex); store_.internal_sources.insert(source); } @@ -52,102 +44,30 @@ void TargetSerialization::UpdateStore(const TargetSchema &store) { // PRIVATE bool TargetSerialization::Verify(const std::string &serialized_data) { - flatbuffers::Verifier verifier((const uint8_t *)serialized_data.c_str(), - serialized_data.length()); - return fbs::VerifyTargetBuffer(verifier); + (void)serialized_data; + return true; } bool TargetSerialization::Load(const std::string &serialized_data) { - const auto *target = fbs::GetTarget((const void *)serialized_data.c_str()); - if (target == nullptr) { - return false; + json j = json::parse(serialized_data, nullptr, false); + bool loaded = !j.is_discarded(); + + if (loaded) { + try { + load_ = j.get(); + } catch (const std::exception &e) { + env::log_critical(__FUNCTION__, e.what()); + loaded = false; + } } - - extract_path(target->source_files(), load_.internal_sources); - extract_path(target->header_files(), load_.internal_headers); - extract_path(target->pch_files(), load_.internal_pchs); - extract_path(target->lib_deps(), load_.internal_libs); - - extract(target->external_lib_deps(), load_.external_libs); - - extract(target->include_dirs(), load_.include_dirs); - extract(target->lib_dirs(), load_.lib_dirs); - - extract(target->preprocessor_flags(), load_.preprocessor_flags); - extract(target->common_compile_flags(), load_.common_compile_flags); - extract(target->pch_compile_flags(), load_.pch_compile_flags); - extract(target->pch_object_flags(), load_.pch_object_flags); - extract(target->asm_compile_flags(), load_.asm_compile_flags); - extract(target->c_compile_flags(), load_.c_compile_flags); - extract(target->cpp_compile_flags(), load_.cpp_compile_flags); - extract(target->link_flags(), load_.link_flags); - - extract_path(target->compile_dependencies(), - load_.internal_compile_dependencies); - extract_path(target->link_dependencies(), load_.internal_link_dependencies); - - load_.pch_compiled = target->pch_compiled(); - load_.target_linked = target->target_linked(); - return true; + return loaded; } bool TargetSerialization::Store(const fs::path &absolute_serialized_file) { - flatbuffers::FlatBufferBuilder builder; - - auto fbs_target_type = (fbs::TargetType)store_.type; - - auto fbs_source_files = - internal::create_fbs_vector_path(builder, store_.internal_sources); - auto fbs_header_files = - internal::create_fbs_vector_path(builder, store_.internal_headers); - auto fbs_pch_files = - internal::create_fbs_vector_path(builder, store_.internal_pchs); - - auto fbs_lib_deps = - internal::create_fbs_vector_path(builder, store_.internal_libs); - auto fbs_external_lib_deps = - internal::create_fbs_vector_string(builder, store_.external_libs); - - auto fbs_include_dirs = - internal::create_fbs_vector_string(builder, store_.include_dirs); - auto fbs_lib_dirs = - internal::create_fbs_vector_string(builder, store_.lib_dirs); - - auto fbs_preprocessor_flags = - internal::create_fbs_vector_string(builder, store_.preprocessor_flags); - auto fbs_common_compile_flags = - internal::create_fbs_vector_string(builder, store_.common_compile_flags); - auto fbs_pch_compile_flags = - internal::create_fbs_vector_string(builder, store_.pch_compile_flags); - auto fbs_pch_object_flags = - internal::create_fbs_vector_string(builder, store_.pch_object_flags); - auto fbs_asm_compile_flags = - internal::create_fbs_vector_string(builder, store_.asm_compile_flags); - auto fbs_c_compile_flags = - internal::create_fbs_vector_string(builder, store_.c_compile_flags); - auto fbs_cpp_compile_flags = - internal::create_fbs_vector_string(builder, store_.cpp_compile_flags); - auto fbs_link_flags = - internal::create_fbs_vector_string(builder, store_.link_flags); - - auto fbs_compile_dependencies = internal::create_fbs_vector_path( - builder, store_.internal_compile_dependencies); - auto fbs_link_dependencies = internal::create_fbs_vector_path( - builder, store_.internal_link_dependencies); - - auto fbs_target = fbs::CreateTargetDirect( - builder, store_.name.c_str(), fbs_target_type, &fbs_source_files, - &fbs_header_files, &fbs_pch_files, &fbs_lib_deps, &fbs_external_lib_deps, - &fbs_include_dirs, &fbs_lib_dirs, &fbs_preprocessor_flags, - &fbs_common_compile_flags, &fbs_pch_compile_flags, &fbs_pch_object_flags, - &fbs_asm_compile_flags, &fbs_c_compile_flags, &fbs_cpp_compile_flags, - &fbs_link_flags, &fbs_compile_dependencies, &fbs_link_dependencies, - store_.pch_compiled, store_.target_linked); - fbs::FinishTargetBuffer(builder, fbs_target); - - return env::save_file(path_as_string(absolute_serialized_file).c_str(), - (const char *)builder.GetBufferPointer(), - builder.GetSize(), true); + json j = store_; + auto data = j.dump(4); + return env::save_file(path_as_string(absolute_serialized_file).c_str(), data, + false); } } // namespace buildcc::internal diff --git a/buildcc/schema/target.fbs b/buildcc/schema/target.fbs deleted file mode 100644 index 0eff9a0e..00000000 --- a/buildcc/schema/target.fbs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2021-2022 Niket Naidu. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -include "path.fbs"; - -namespace schema.internal; - -enum TargetType : byte { - Executable, - StaticLibrary, - DynamicLibrary -} - -// TODO, Check if Toolchain needs to be added to Target -table Target { - // Metadata - name:string (key); - type:TargetType; - - // Input - // Files - source_files:[Path]; - header_files:[Path]; - pch_files:[Path]; - lib_deps:[Path]; - - // Links - external_lib_deps:[string]; - - // Directories - include_dirs:[string]; - lib_dirs:[string]; - - // Flags - preprocessor_flags:[string]; - common_compile_flags:[string]; - pch_compile_flags:[string]; - pch_object_flags:[string]; - asm_compile_flags:[string]; - c_compile_flags:[string]; - cpp_compile_flags:[string]; - link_flags:[string]; - - // Additional dependencies - compile_dependencies:[Path]; - link_dependencies:[Path]; - - // Output - // Does not need to be stored - - // State - pch_compiled:bool; - target_linked:bool; -} - -root_type Target; diff --git a/buildcc/schema/test/test_custom_generator_serialization.cpp b/buildcc/schema/test/test_custom_generator_serialization.cpp index 3c215257..e7411470 100644 --- a/buildcc/schema/test/test_custom_generator_serialization.cpp +++ b/buildcc/schema/test/test_custom_generator_serialization.cpp @@ -1,9 +1,5 @@ #include "schema/custom_generator_serialization.h" -#include "schema/private/schema_util.h" - -#include "flatbuffers/flatbuffers.h" - // NOTE, Make sure all these includes are AFTER the system and header includes #include "CppUTest/CommandLineTestRunner.h" #include "CppUTest/MemoryLeakDetectorNewMacros.h" @@ -24,7 +20,7 @@ TEST(CustomGeneratorSerializationTestGroup, JsonParse_Failure) { { // JSON Parse fails buildcc::internal::CustomGeneratorSerialization serialization( - "dump/JsonParseFailure.json"); + "dump/CustomGeneratorJsonParseFailure.json"); buildcc::env::save_file(serialization.GetSerializedFile().string().c_str(), std::string(""), false); @@ -35,7 +31,7 @@ TEST(CustomGeneratorSerializationTestGroup, JsonParse_Failure) { { // Custom Generator Schema conversion fails buildcc::internal::CustomGeneratorSerialization serialization( - "dump/JsonParseFailure.json"); + "dump/CustomGeneratorJsonParseFailure.json"); auto data = R"({"name": ""})"; buildcc::env::save_file(serialization.GetSerializedFile().string().c_str(), @@ -47,7 +43,7 @@ TEST(CustomGeneratorSerializationTestGroup, JsonParse_Failure) { TEST(CustomGeneratorSerializationTestGroup, FormatEmptyCheck) { buildcc::internal::CustomGeneratorSerialization serialization( - "dump/FormatEmptyCheck.json"); + "dump/CustomGeneratorFormatEmptyCheck.json"); bool stored = serialization.StoreToFile(); CHECK_TRUE(stored); @@ -56,13 +52,13 @@ TEST(CustomGeneratorSerializationTestGroup, FormatEmptyCheck) { TEST(CustomGeneratorSerializationTestGroup, EmptyFile_Failure) { { buildcc::internal::CustomGeneratorSerialization serialization( - "dump/EmptyFile.json"); + "dump/CustomGeneratorEmptyFile.json"); CHECK_FALSE(serialization.LoadFromFile()); } { buildcc::internal::CustomGeneratorSerialization serialization( - "dump/EmptyFile.json"); + "dump/CustomGeneratorEmptyFile.json"); buildcc::env::save_file(serialization.GetSerializedFile().string().c_str(), "", false); CHECK_FALSE(serialization.LoadFromFile()); diff --git a/buildcc/schema/test/test_target_serialization.cpp b/buildcc/schema/test/test_target_serialization.cpp new file mode 100644 index 00000000..522a6b64 --- /dev/null +++ b/buildcc/schema/test/test_target_serialization.cpp @@ -0,0 +1,196 @@ +#include "schema/target_serialization.h" + +#include "nlohmann/json.hpp" + +using json = nlohmann::ordered_json; + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(TargetSerializationTestGroup) +{ + void teardown() { + mock().clear(); + } +}; +// clang-format on + +TEST(TargetSerializationTestGroup, TargetType) { + buildcc::TargetType type; + json j; + + { + j = buildcc::kTargetTypeInfo[0].first; + from_json(j, type); + CHECK_TRUE(type == buildcc::kTargetTypeInfo[0].second); + } + + { + j = buildcc::kTargetTypeInfo[1].first; + from_json(j, type); + CHECK_TRUE(type == buildcc::kTargetTypeInfo[1].second); + } + + { + j = buildcc::kTargetTypeInfo[2].first; + from_json(j, type); + CHECK_TRUE(type == buildcc::kTargetTypeInfo[2].second); + } + + { + j = "should_not_exist"; + from_json(j, type); + CHECK_TRUE(type == buildcc::TargetType::Undefined); + } + + { + j = nullptr; + from_json(j, type); + CHECK_TRUE(type == buildcc::TargetType::Undefined); + } +} + +TEST(TargetSerializationTestGroup, TargetSerialization_TargetType) { + { + // Target Type executable + buildcc::internal::TargetSerialization serialization( + "dump/TargetTypeTest.json"); + + buildcc::internal::TargetSchema schema; + schema.type = buildcc::TargetType::Executable; + serialization.UpdateStore(schema); + bool store = serialization.StoreToFile(); + CHECK_TRUE(store); + + bool load = serialization.LoadFromFile(); + CHECK_TRUE(load); + CHECK_TRUE(serialization.GetLoad().type == buildcc::TargetType::Executable); + } + + { + // Target Type static library + buildcc::internal::TargetSerialization serialization( + "dump/TargetTypeTest.json"); + + buildcc::internal::TargetSchema schema; + schema.type = buildcc::TargetType::StaticLibrary; + serialization.UpdateStore(schema); + bool store = serialization.StoreToFile(); + CHECK_TRUE(store); + + bool load = serialization.LoadFromFile(); + CHECK_TRUE(load); + CHECK_TRUE(serialization.GetLoad().type == + buildcc::TargetType::StaticLibrary); + } + + { + // Target Type dynamic library + buildcc::internal::TargetSerialization serialization( + "dump/TargetTypeTest.json"); + + buildcc::internal::TargetSchema schema; + schema.type = buildcc::TargetType::DynamicLibrary; + serialization.UpdateStore(schema); + bool store = serialization.StoreToFile(); + CHECK_TRUE(store); + + bool load = serialization.LoadFromFile(); + CHECK_TRUE(load); + CHECK_TRUE(serialization.GetLoad().type == + buildcc::TargetType::DynamicLibrary); + } + + { + // Target Type undefined + buildcc::internal::TargetSerialization serialization( + "dump/TargetTypeTest.json"); + + buildcc::internal::TargetSchema schema; + schema.type = buildcc::TargetType::Undefined; + serialization.UpdateStore(schema); + bool store = serialization.StoreToFile(); + CHECK_TRUE(store); + + bool load = serialization.LoadFromFile(); + CHECK_TRUE(load); + CHECK_TRUE(serialization.GetLoad().type == buildcc::TargetType::Undefined); + } + + { + // Target Type random value + buildcc::internal::TargetSerialization serialization( + "dump/TargetTypeTest.json"); + + buildcc::internal::TargetSchema schema; + schema.type = (buildcc::TargetType)65535; + serialization.UpdateStore(schema); + bool store = serialization.StoreToFile(); + CHECK_TRUE(store); + + bool load = serialization.LoadFromFile(); + CHECK_TRUE(load); + CHECK_TRUE(serialization.GetLoad().type == buildcc::TargetType::Undefined); + } +} + +TEST(TargetSerializationTestGroup, JsonParse_Failure) { + { + // JSON Parse fails + buildcc::internal::TargetSerialization serialization( + "dump/TargetJsonParseFailure.json"); + + buildcc::env::save_file(serialization.GetSerializedFile().string().c_str(), + std::string(""), false); + bool loaded = serialization.LoadFromFile(); + CHECK_FALSE(loaded); + } + + { + // Custom Generator Schema conversion fails + buildcc::internal::TargetSerialization serialization( + "dump/TargetJsonParseFailure.json"); + + auto data = R"({"name": ""})"; + buildcc::env::save_file(serialization.GetSerializedFile().string().c_str(), + data, false); + bool loaded = serialization.LoadFromFile(); + CHECK_FALSE(loaded); + } +} + +TEST(TargetSerializationTestGroup, FormatEmptyCheck) { + buildcc::internal::TargetSerialization serialization( + "dump/TargetFormatEmptyCheck.json"); + + bool stored = serialization.StoreToFile(); + CHECK_TRUE(stored); + + bool loaded = serialization.LoadFromFile(); + CHECK_TRUE(loaded); +} + +TEST(TargetSerializationTestGroup, EmptyFile_Failure) { + { + buildcc::internal::TargetSerialization serialization( + "dump/TargetEmptyFile.json"); + CHECK_FALSE(serialization.LoadFromFile()); + } + + { + buildcc::internal::TargetSerialization serialization( + "dump/TargetEmptyFile.json"); + buildcc::env::save_file(serialization.GetSerializedFile().string().c_str(), + "", false); + CHECK_FALSE(serialization.LoadFromFile()); + } +} + +int main(int ac, char **av) { + return CommandLineTestRunner::RunAllTests(ac, av); +} From 57a26a59f8b823b6d049a858d6dc48137c22e8cf Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 5 Nov 2022 21:39:21 -0700 Subject: [PATCH 31/35] [Serialization] Removing flatbuffer/flexbuffer usage and library from BuildCC (#226) --- .gitmodules | 9 ++--- CMakeLists.txt | 5 --- CMakePresets.json | 6 ---- DEPENDENCIES.md | 10 +++++- README.md | 2 -- bootstrap/CMakeLists.txt | 1 - bootstrap/include/bootstrap/build_buildcc.h | 17 +++------- bootstrap/main.buildcc.cpp | 1 - bootstrap/src/build_buildcc.cpp | 31 ++++-------------- buildcc/CMakeLists.txt | 3 +- .../target/src/generator/file_generator.cpp | 31 ++++-------------- .../test/target/test_custom_generator.cpp | 16 ++++----- buildcc/schema/cmake/schema.cmake | 2 -- buildexe/CMakeLists.txt | 1 - buildexe/buildexe.cpp | 6 ---- cmake/coverage/gcovr.cmake | 1 - cmake/coverage/lcov.cmake | 1 - cmake/target/flatbuffers.cmake | 13 -------- doc/faq/why_this_lib.md | 4 +++ .../buildcc_interface_lib.PNG | Bin 171128 -> 159948 bytes .../buildcc_single_lib.PNG | Bin 146121 -> 135798 bytes doc/user/installation_using_cmake.md | 1 - docs/source/arch/project_layout.rst | 6 ++-- docs/source/arch/software_heirarchy.rst | 8 ++--- docs/source/arch/testing.rst | 12 +++---- docs/source/examples/gcc.rst | 4 +-- .../source/getting_started/buildexe_setup.rst | 2 +- docs/source/intro/toc.rst | 4 +-- docs/source/user_api/generator.rst | 22 +++++++++---- docs/source/user_api/target.rst | 5 --- docs/source/user_api/toolchain_utils.rst | 5 --- example/gcc/AfterInstall/CMakeLists.txt | 2 -- third_party/flatbuffers | 1 - 33 files changed, 74 insertions(+), 158 deletions(-) delete mode 100644 cmake/target/flatbuffers.cmake delete mode 160000 third_party/flatbuffers diff --git a/.gitmodules b/.gitmodules index 081a123b..97699a1c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ -[submodule "flatbuffers"] - path = third_party/flatbuffers - url = https://github.com/google/flatbuffers.git +[submodule "json"] + path = third_party/json + url = https://github.com/nlohmann/json.git [submodule "spdlog"] path = third_party/spdlog url = https://github.com/gabime/spdlog.git @@ -22,6 +22,3 @@ [submodule "optional"] path = third_party/tl_optional url = https://github.com/TartanLlama/optional.git -[submodule "json"] - path = third_party/json - url = https://github.com/nlohmann/json.git diff --git a/CMakeLists.txt b/CMakeLists.txt index ec6ce113..669219e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,8 +12,6 @@ project(BuildCC # User options option(BUILDCC_INSTALL "Enable BuildCC Installation" ON) -option(BUILDCC_FLATBUFFERS_FLATC "Build Flatbuffer::Flatc Compiler" ON) - option(BUILDCC_BUILD_AS_SINGLE_LIB "Build all internal libs and modules as part of the buildcc library" ON) option(BUILDCC_BUILD_AS_INTERFACE "Build all internal libs and modules seperately and link" OFF) @@ -34,7 +32,6 @@ option(BUILDCC_DOCUMENTATION "Enable Documentation" OFF) # Compiler options # NOTE, This option is required for clang compilers, architecture x86_64-pc-windows-msvc -# Flatbuffers library uses `std::system` internally which causes a deprecated error option(BUILDCC_NO_DEPRECATED "Disable Deprecated" OFF) if (${BUILDCC_NO_DEPRECATED}) add_compile_options("-Wno-deprecated") @@ -72,9 +69,7 @@ include(cmake/tool/cppcheck.cmake) include(cmake/tool/doxygen.cmake) # Libraries -include(cmake/target/flatbuffers.cmake) include(cmake/target/json.cmake) - include(cmake/target/fmt.cmake) include(cmake/target/spdlog.cmake) include(cmake/target/cli11.cmake) diff --git a/CMakePresets.json b/CMakePresets.json index fcc2836a..6b1d4c4b 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -17,7 +17,6 @@ "CMAKE_C_COMPILER": "gcc", "CMAKE_CXX_COMPILER": "g++", "BUILDCC_INSTALL": true, - "BUILDCC_FLATBUFFERS_FLATC": true, "BUILDCC_BUILD_AS_SINGLE_LIB": true, "BUILDCC_BUILD_AS_INTERFACE": true, "BUILDCC_BUILDEXE": true, @@ -42,7 +41,6 @@ "CMAKE_C_COMPILER": "gcc", "CMAKE_CXX_COMPILER": "g++", "BUILDCC_INSTALL": true, - "BUILDCC_FLATBUFFERS_FLATC": true, "BUILDCC_BUILD_AS_SINGLE_LIB": true, "BUILDCC_BUILD_AS_INTERFACE": false, "BUILDCC_BUILDEXE": true, @@ -67,7 +65,6 @@ "CMAKE_C_COMPILER": "gcc", "CMAKE_CXX_COMPILER": "g++", "BUILDCC_INSTALL": true, - "BUILDCC_FLATBUFFERS_FLATC": true, "BUILDCC_BUILD_AS_SINGLE_LIB": false, "BUILDCC_BUILD_AS_INTERFACE": true, "BUILDCC_BUILDEXE": false, @@ -92,7 +89,6 @@ "CMAKE_C_COMPILER": "clang", "CMAKE_CXX_COMPILER": "clang++", "BUILDCC_INSTALL": true, - "BUILDCC_FLATBUFFERS_FLATC": true, "BUILDCC_BUILD_AS_SINGLE_LIB": true, "BUILDCC_BUILD_AS_INTERFACE": true, "BUILDCC_BUILDEXE": true, @@ -114,7 +110,6 @@ "binaryDir": "${sourceDir}/_build_msvc_dev_all", "cacheVariables": { "BUILDCC_INSTALL": true, - "BUILDCC_FLATBUFFERS_FLATC": true, "BUILDCC_BUILD_AS_SINGLE_LIB": true, "BUILDCC_BUILD_AS_INTERFACE": true, "BUILDCC_BUILDEXE": true, @@ -136,7 +131,6 @@ "binaryDir": "${sourceDir}/_build_msvc_analysis", "cacheVariables": { "BUILDCC_INSTALL": false, - "BUILDCC_FLATBUFFERS_FLATC": true, "BUILDCC_BUILD_AS_SINGLE_LIB": true, "BUILDCC_BUILD_AS_INTERFACE": false, "BUILDCC_BUILDEXE": false, diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index fe9d47bc..b19d3a63 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -2,13 +2,21 @@ These third party libraries are added as submodules since they aren't meant to be modified by this project. +### Adding a submodule + `git submodule add [git_url] third_party/[foldername]` +### Removing a submodule + +- `git rm --cached path_to_submodule` (no trailing slash) +- Delete relevant line from `.gitmodules` file +- Delete relevant section from `.git/config` file + ## Main - fmt (Formatting) - spdlog (Logging) -- flatbuffers (Serialization) +- json (Serialization) - CLI11 (Argument Parsing) - Taskflow (Parallel Programming) diff --git a/README.md b/README.md index 725ca12c..d3abdfa3 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ Build C, C++ and ASM files in C++ - `C++17 filesystem` library support - `C++11 thread` library support - Third Party Libraries (See License below) - - Flatbuffers v2.0.0 - Nlohmann::Json v3.11.2 - Taskflow v3.1.0 - CLI11 v2.1.0 @@ -178,7 +177,6 @@ _BuildCC_ is licensed under the Apache License, Version 2.0. See [LICENSE](LICEN - [Taskflow](https://github.com/taskflow/taskflow) (Parallel Programming) [MIT License] [Header Only] - See also [3rd-Party](https://github.com/taskflow/taskflow/tree/master/3rd-party) used by Taskflow - [Nlohmann::Json](https://github.com/nlohmann/json) (JSON Serialization) [MIT License] [Header Only] -- [Flatbuffers](https://github.com/google/flatbuffers) (Serialization) [Apache-2.0 License] - [CLI11](https://github.com/CLIUtils/CLI11) (Argument Parsing) [BSD-3-Clause License] [Header Only] - [CppUTest](https://github.com/cpputest/cpputest) (Unit Testing/Mocking) [BSD-3-Clause License] - [Tl::Optional](https://github.com/TartanLlama/optional) (Optional support) [CC0-1.0 License] diff --git a/bootstrap/CMakeLists.txt b/bootstrap/CMakeLists.txt index 3c50e1b8..924fa351 100644 --- a/bootstrap/CMakeLists.txt +++ b/bootstrap/CMakeLists.txt @@ -2,7 +2,6 @@ add_executable(buildcc_lib_bootstrap main.buildcc.cpp ) target_sources(buildcc_lib_bootstrap PRIVATE - src/build_flatbuffers.cpp src/build_nlohmann_json.cpp src/build_cli11.cpp src/build_fmtlib.cpp diff --git a/bootstrap/include/bootstrap/build_buildcc.h b/bootstrap/include/bootstrap/build_buildcc.h index da4cc9f1..bef6fdf3 100644 --- a/bootstrap/include/bootstrap/build_buildcc.h +++ b/bootstrap/include/bootstrap/build_buildcc.h @@ -20,7 +20,6 @@ #include "buildcc.h" #include "build_cli11.h" -#include "build_flatbuffers.h" #include "build_fmtlib.h" #include "build_nlohmann_json.h" #include "build_spdlog.h" @@ -30,11 +29,10 @@ namespace buildcc { -void buildcc_cb(BaseTarget &target, const TargetInfo &flatbuffers_ho, - const TargetInfo &nlohmann_json_ho, const TargetInfo &fmt_ho, - const TargetInfo &spdlog_ho, const TargetInfo &cli11_ho, - const TargetInfo &taskflow_ho, const TargetInfo &tl_optional_ho, - const BaseTarget &tpl); +void buildcc_cb(BaseTarget &target, const TargetInfo &nlohmann_json_ho, + const TargetInfo &fmt_ho, const TargetInfo &spdlog_ho, + const TargetInfo &cli11_ho, const TargetInfo &taskflow_ho, + const TargetInfo &tl_optional_ho, const BaseTarget &tpl); /** * @brief @@ -43,7 +41,6 @@ void buildcc_cb(BaseTarget &target, const TargetInfo &flatbuffers_ho, class BuildBuildCC { public: // TargetInfo / Header Only - static constexpr const char *const kFlatbuffersHoName = "flatbuffers_ho"; static constexpr const char *const kNlohmannJsonHoName = "nlohmann_json_ho"; static constexpr const char *const kCli11HoName = "cli11_ho"; static constexpr const char *const kFmtHoName = "fmtlib_ho"; @@ -77,12 +74,6 @@ class BuildBuildCC { private: void Initialize(); - ExecutableTarget_generic &GetFlatc() { - return storage_.Ref(kFlatcExeName); - } - TargetInfo &GetFlatbuffersHo() { - return storage_.Ref(kFlatbuffersHoName); - } TargetInfo &GetNlohmannJsonHo() { return storage_.Ref(kNlohmannJsonHoName); } diff --git a/bootstrap/main.buildcc.cpp b/bootstrap/main.buildcc.cpp index aac2276f..4eafe255 100644 --- a/bootstrap/main.buildcc.cpp +++ b/bootstrap/main.buildcc.cpp @@ -17,7 +17,6 @@ #include "buildcc.h" #include "bootstrap/build_cli11.h" -#include "bootstrap/build_flatbuffers.h" #include "bootstrap/build_fmtlib.h" #include "bootstrap/build_spdlog.h" #include "bootstrap/build_taskflow.h" diff --git a/bootstrap/src/build_buildcc.cpp b/bootstrap/src/build_buildcc.cpp index 662e0728..38c2072c 100644 --- a/bootstrap/src/build_buildcc.cpp +++ b/bootstrap/src/build_buildcc.cpp @@ -18,11 +18,10 @@ namespace buildcc { -void buildcc_cb(BaseTarget &target, const TargetInfo &flatbuffers_ho, - const TargetInfo &nlohmann_json_ho, const TargetInfo &fmt_ho, - const TargetInfo &spdlog_ho, const TargetInfo &cli11_ho, - const TargetInfo &taskflow_ho, const TargetInfo &tl_optional_ho, - const BaseTarget &tpl) { +void buildcc_cb(BaseTarget &target, const TargetInfo &nlohmann_json_ho, + const TargetInfo &fmt_ho, const TargetInfo &spdlog_ho, + const TargetInfo &cli11_ho, const TargetInfo &taskflow_ho, + const TargetInfo &tl_optional_ho, const BaseTarget &tpl) { // NOTE, Build as single lib target.AddIncludeDir("", true); @@ -88,9 +87,6 @@ void buildcc_cb(BaseTarget &target, const TargetInfo &flatbuffers_ho, SyncOption::HeaderFiles, }; - // FLATBUFFERS HO - target.Insert(flatbuffers_ho, kInsertOptions); - // NLOHMANN JSON HO target.Insert(nlohmann_json_ho, kInsertOptions); @@ -175,17 +171,6 @@ static void global_flags_cb(TargetInfo &global_info, } void BuildBuildCC::Initialize() { - (void)storage_.Add( - kFlatcExeName, kFlatcExeName, toolchain_, - TargetEnv(env_.GetTargetRootDir() / "third_party" / "flatbuffers", - env_.GetTargetBuildDir())); - - // Flatbuffers HO lib - (void)storage_.Add( - kFlatbuffersHoName, toolchain_, - TargetEnv(env_.GetTargetRootDir() / "third_party" / "flatbuffers", - env_.GetTargetBuildDir())); - // Nlohmann json HO lib (void)storage_.Add( kNlohmannJsonHoName, toolchain_, @@ -240,7 +225,6 @@ void BuildBuildCC::Initialize() { } void BuildBuildCC::Setup(const ArgToolchainState &state) { - auto &flatbuffers_ho_lib = GetFlatbuffersHo(); auto &nlohmann_json_ho_lib = GetNlohmannJsonHo(); auto &cli11_ho_lib = GetCli11Ho(); auto &fmt_ho_lib = GetFmtHo(); @@ -250,7 +234,6 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { auto &tpl_lib = GetTpl(); auto &buildcc_lib = GetBuildcc(); Reg::Toolchain(state) - .Func(flatbuffers_ho_cb, flatbuffers_ho_lib) .Func(nlohmann_json_ho_cb, nlohmann_json_ho_lib) .Func(cli11_ho_cb, cli11_ho_lib) .Func(fmt_ho_cb, fmt_ho_lib) @@ -260,9 +243,9 @@ void BuildBuildCC::Setup(const ArgToolchainState &state) { .Func(global_flags_cb, tpl_lib, toolchain_) .Build(tpl_cb, tpl_lib) .Func(global_flags_cb, buildcc_lib, toolchain_) - .Build(buildcc_cb, buildcc_lib, flatbuffers_ho_lib, nlohmann_json_ho_lib, - fmt_ho_lib, spdlog_ho_lib, cli11_ho_lib, taskflow_ho_lib, - tl_optional_ho_lib, tpl_lib) + .Build(buildcc_cb, buildcc_lib, nlohmann_json_ho_lib, fmt_ho_lib, + spdlog_ho_lib, cli11_ho_lib, taskflow_ho_lib, tl_optional_ho_lib, + tpl_lib) .Dep(buildcc_lib, tpl_lib); } diff --git a/buildcc/CMakeLists.txt b/buildcc/CMakeLists.txt index eede4309..074288d2 100644 --- a/buildcc/CMakeLists.txt +++ b/buildcc/CMakeLists.txt @@ -13,7 +13,6 @@ if(${BUILDCC_BUILD_AS_SINGLE_LIB}) target_link_libraries(buildcc PUBLIC fmt::fmt tl::optional - flatbuffers nlohmann_json::nlohmann_json Taskflow CLI11::CLI11 @@ -29,7 +28,7 @@ if(${BUILDCC_BUILD_AS_SINGLE_LIB}) endif() endif() -# Flatbuffers schema +# Schema add_subdirectory(schema) # Environment diff --git a/buildcc/lib/target/src/generator/file_generator.cpp b/buildcc/lib/target/src/generator/file_generator.cpp index 7ec3deb2..5cdb592f 100644 --- a/buildcc/lib/target/src/generator/file_generator.cpp +++ b/buildcc/lib/target/src/generator/file_generator.cpp @@ -18,8 +18,6 @@ #include -#include "flatbuffers/flexbuffers.h" - #include "env/assert_fatal.h" namespace { @@ -32,11 +30,9 @@ class FileGeneratorBlobHandler : public buildcc::CustomBlobHandler { // serialized_data has already been verified static std::vector Deserialize(const std::vector &serialized_data) { + json j = json::from_msgpack(serialized_data, true, false); std::vector deserialized; - auto flex_vect = flexbuffers::GetRoot(serialized_data).AsVector(); - for (size_t i = 0; i < flex_vect.size(); i++) { - deserialized.emplace_back(flex_vect[i].AsString().str()); - } + j.get_to(deserialized); return deserialized; } @@ -44,17 +40,8 @@ class FileGeneratorBlobHandler : public buildcc::CustomBlobHandler { const std::vector &commands_; bool Verify(const std::vector &serialized_data) const override { - auto flex_ref = flexbuffers::GetRoot(serialized_data); - if (!flex_ref.IsVector()) { - return false; - } - auto flex_vect = flex_ref.AsVector(); - for (size_t i = 0; i < flex_vect.size(); i++) { - if (!flex_vect[i].IsString()) { - return false; - } - } - return true; + json j = json::from_msgpack(serialized_data, true, false); + return !j.is_discarded(); } bool IsEqual(const std::vector &previous, @@ -63,14 +50,8 @@ class FileGeneratorBlobHandler : public buildcc::CustomBlobHandler { } std::vector Serialize() const override { - flexbuffers::Builder builder; - builder.Vector([&]() { - for (const auto &c : commands_) { - builder.Add(c); - } - }); - builder.Finish(); - return builder.GetBuffer(); + json j = commands_; + return json::to_msgpack(j); } }; diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp index fdc0ba9c..a6c6597b 100644 --- a/buildcc/lib/target/test/target/test_custom_generator.cpp +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -4,8 +4,6 @@ #include "expect_custom_generator.h" #include "test_target_util.h" -#include "flatbuffers/flexbuffers.h" - #include // NOTE, Make sure all these includes are AFTER the system and header includes @@ -986,7 +984,8 @@ class MyCustomBlobHandler : public buildcc::CustomBlobHandler { private: bool Verify(const std::vector &serialized_data) const override { - return flexbuffers::GetRoot(serialized_data).IsInt(); + json j = json::from_msgpack(serialized_data); + return !j.is_discarded(); } bool IsEqual(const std::vector &previous, @@ -995,15 +994,16 @@ class MyCustomBlobHandler : public buildcc::CustomBlobHandler { } std::vector Serialize() const override { - flexbuffers::Builder builder; - builder.Add(recheck_value); - builder.Finish(); - return builder.GetBuffer(); + json j = recheck_value; + return json::to_msgpack(j); } // serialized_data has already been verified int32_t Deserialize(const std::vector &serialized_data) const { - return flexbuffers::GetRoot(serialized_data).AsInt32(); + json j = json::from_msgpack(serialized_data); + int32_t deserialized; + j.get_to(deserialized); + return deserialized; } }; diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake index 20ba85cf..a7703233 100644 --- a/buildcc/schema/cmake/schema.cmake +++ b/buildcc/schema/cmake/schema.cmake @@ -20,7 +20,6 @@ if (${TESTING}) ) target_link_libraries(mock_schema PUBLIC mock_env - flatbuffers nlohmann_json::nlohmann_json CppUTest @@ -88,7 +87,6 @@ if(${BUILDCC_BUILD_AS_INTERFACE}) ) target_link_libraries(schema PUBLIC env - flatbuffers nlohmann_json::nlohmann_json ) target_include_directories(schema PRIVATE diff --git a/buildexe/CMakeLists.txt b/buildexe/CMakeLists.txt index 73bc7d2d..b78f1030 100644 --- a/buildexe/CMakeLists.txt +++ b/buildexe/CMakeLists.txt @@ -16,7 +16,6 @@ add_executable(buildexe target_sources(buildexe PRIVATE ../bootstrap/src/build_buildcc.cpp ../bootstrap/src/build_cli11.cpp - ../bootstrap/src/build_flatbuffers.cpp ../bootstrap/src/build_nlohmann_json.cpp ../bootstrap/src/build_fmtlib.cpp ../bootstrap/src/build_spdlog.cpp diff --git a/buildexe/buildexe.cpp b/buildexe/buildexe.cpp index 08926b0a..a93d554f 100644 --- a/buildexe/buildexe.cpp +++ b/buildexe/buildexe.cpp @@ -22,12 +22,6 @@ #include "buildexe/toolchain_setup.h" #include "bootstrap/build_buildcc.h" -#include "bootstrap/build_cli11.h" -#include "bootstrap/build_flatbuffers.h" -#include "bootstrap/build_fmtlib.h" -#include "bootstrap/build_spdlog.h" -#include "bootstrap/build_taskflow.h" -#include "bootstrap/build_tpl.h" using namespace buildcc; diff --git a/cmake/coverage/gcovr.cmake b/cmake/coverage/gcovr.cmake index 9bba8891..d127fe42 100644 --- a/cmake/coverage/gcovr.cmake +++ b/cmake/coverage/gcovr.cmake @@ -9,7 +9,6 @@ else() message("GCOVR at ${gcovr_program}") set(GCOVR_REMOVE_OPTIONS - --exclude "(.+/)?flatbuffers(.+/)?" --exclude "(.+/)?spdlog(.+/)?" --exclude "(.+/)?fmt(.+/)?" --exclude "(.+/)?taskflow(.+/)?" diff --git a/cmake/coverage/lcov.cmake b/cmake/coverage/lcov.cmake index f7551a9b..8860f459 100644 --- a/cmake/coverage/lcov.cmake +++ b/cmake/coverage/lcov.cmake @@ -21,7 +21,6 @@ else() "*/CppUTest*" "*/fmt*" "*/spdlog*" - "*/flatbuffers*" "*/taskflow*" "*/CLI11*" "*/generated*" diff --git a/cmake/target/flatbuffers.cmake b/cmake/target/flatbuffers.cmake deleted file mode 100644 index dc4e1c1b..00000000 --- a/cmake/target/flatbuffers.cmake +++ /dev/null @@ -1,13 +0,0 @@ - -# TODO, Update FLATBUFFERS option to conditionally compile FLATC - -# Set flatbuffer specific options here -set(FLATBUFFERS_BUILD_CPP17 ON CACHE BOOL "Flatbuffers C++17 support") -set(FLATBUFFERS_BUILD_TESTS OFF CACHE BOOL "Flatbuffers build tests") -set(FLATBUFFERS_BUILD_FLATC ${BUILDCC_FLATBUFFERS_FLATC} CACHE BOOL "Flatbuffers build flatc") -set(FLATBUFFERS_BUILD_FLATHASH OFF CACHE BOOL "Flatbuffers build flathash") -set(FLATBUFFERS_BUILD_FLATLIB ON CACHE BOOL "Flatbuffers build flatlib") -set(FLATBUFFERS_LIBCXX_WITH_CLANG OFF CACHE BOOL "Flatbuffers LIBCXX") -set(FLATBUFFERS_INSTALL ON CACHE BOOL "Enable the installation of targets.") -set(FLATBUFFERS_ENABLE_PCH ${BUILDCC_PRECOMPILE_HEADERS} CACHE BOOL "Flatbuffers PCH") -add_subdirectory(third_party/flatbuffers) diff --git a/doc/faq/why_this_lib.md b/doc/faq/why_this_lib.md index f14544cd..a44368fb 100644 --- a/doc/faq/why_this_lib.md +++ b/doc/faq/why_this_lib.md @@ -31,6 +31,10 @@ Also see [Target::BuildRecompile() in build.cpp](../../buildcc/lib/target/src/ta - For example: an array cannot be a root when writing your schema. - `flexbuffer` can be used to generate flexibile + efficient JSON. +# JSON + +- See https://github.com/coder137/build_in_cpp/issues/222 + # Fmtlib and Spdlog - Fmtlib and Spdlog are extremely popular libraries for formatting and logging. diff --git a/doc/software_architecture/buildcc_interface_lib.PNG b/doc/software_architecture/buildcc_interface_lib.PNG index 332d0398b66ab2229a0339e7c2f217d49d1e06b4..58a0d56b748dfbd438b0bdb36e575473ff7848e0 100644 GIT binary patch literal 159948 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 literal 171128 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%0DQPC>zD`PY2d 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

xb#7I0?;2Vc+@l#7gY#?ITkR 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 z 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℞+lE z8iqg3Lkbh;1RC;TNN1m`Tjkq@0E6De`g=Jx0Sk>qzWJNrbO+Nq)aLTrr@!9aJ1!@NEiRQ)Bgd}{|mA{F3L z!@B5A7F>$QQIFU4zvSP@yPcV^fj{?=E`?<0%2fa?C?RyyI@Dsq;-gx8_O5D~q5Y-+ zviAd8Mn>H>#7}l2mCj-6K&A@)!Y1%cCoFoXim?ExR$bHz`3}E9RegVhebQigC8MPV zLJC2eAfKXgE8tmYv(pB5ZYLX3z|0D*`-NX$A#T;Ul058I*lyFMZW`~Nn+pRYZQ1WH zBGz`~0XT7#NHe>@YMm;Ve0%knyWlgZ>)l7v|flj(;IxPnKT7+^sf= zaA^#dB?~t9ZD4F!k&gxQEuq@ihEYSWOa~(5!52~6!Z(bsR*S{r5bPdLu z>Mvfhq#aYRFlo~N<>xcz0)V3&6O_la27oh=1OeQtAFpC6EK(9MRBm3Lb(KduNAHD|Wsb7u_2}XcJIl3_)o+5807R>! znUV(?T3GVQ)LbqF3M15 zF=arC0lo6|9ca(on3oZ~JcxNRqj~>9sRKIjfmrO=l|MvBwi5up!Sf#!D4AMSLW`W) zKvwgdMl@(_HaH!FEs*so6+-wM zFg+dqzu(eOehZKw!MT$ioCJVlJCLI=Xx1|&C9%7Ki(Q@I=}wdK6JbKOY(dJBuPZbm z(N$#c!Zge`hI=TRR##8#bxNBr?*SrIzf~VuM~3t&;eWr*Mt&W=lLI;EkzFMna8{$DE|7MP;z3_Av^R4gJ4y{Alx}RS4Efw=lnG?HX*R5hzHJ` zu`KP|NX+?#DENP2z{)jRmUSxjwC(Seuc62VLTsQT#lZ57a68QANNPuixh{UNSMNp3 zV=vpHHUHHv47kCdm6+?xMsTj$y7+c~qoS!n8YaH7#Z(32nF9VS-=^eLA}{BQg9b9> zN#FqECWZY*r|XA7q`+7KcsAp-ofhZM(9k+U@dQ?lUOjXtYu;pD4qzoZ-m@E=gEas* zLwTY-7CSSC^f@5c!F%_On(&8Zi2tBV( zUr0Wnc?)h%+eKqR??l!Go;exRj`DC3Mnn>S)7D+CyK2SnU!31e39NY;68B|6GjNGA z`&{(~sR7%FiJ!zJQRA;Y&8Jvk5?dg$X9=?i93yka!E}Qp1&ih$Z@$Q!J#g!wMfKyR zZGft&DqN9@q6lFKH5UOn?DD_yT>qMo^Kr3MT(Sxim8290cXB#>Ags3EsG;d-y#)gs zsxxF$$?0N|VS52n9*LJgxb%g5|hTy-z-~5sCBjV$sOXQ$v zRn{-Gk#x`JXPyNHT%%DFeQp2^jWa&Tehm#0=CAUYB#L-;+#iTTXhFpg$E`jji_6Ba(deClu>)aRM)57aILd4tfsN4dc%<;ZSvnn{>(pXsQbiV&Z&Kuh7EOi zf2@hay7>(Uzp_$@Gwx7jzpdCm0x*6)%D^wmI(bfZ|#e6BAR|{iQX-_=)@Wtp&nO z+Fsl;%_U4S8xn8~PSQTUzK{Rrp_#XJfchFlt$hi(akmiOPJQDaG%{*xYGV7KNK5U0 zjlJ67Qgac3vsrgsSsxL_pcAbF?t+|5z4gEJSNiFdy4qEhFPvEiF}$pqmHN}NGFf7f zG+Co=GCy9{up9y*-EpnBq@;+MUZQNh)+zVUH>-&jj%fj>UAJ%Fy5-4f>h#rBZ|BaP z+FfGoQbZ7o(^IXXRuS%~xPsOy6vBB(S&h43OE^NEe*Xf`u7Ro+##gXjL8;FJ($`m= zhrbqVryg|AT2htEpS;3|bltKAo!#~;+Oiz|){&VezFO<9GnkJ|RPWn(-Vla23;(_oV|gcWn>Mk5$bmoAYKJ+JSh1i2wpIQbJ4@qOeYnrEW{0n> zS6|5m4uSgP_`Osf(wZ|@TdkC`%Aj%GO<|i!?VV`ojePAXl2O}uLU*&X%C+ntNfLY+ zwAHDV)`y4LpFN7~ylUEyAZnD)N2YuK!$C-6Q>Lje!1B#yrB>4R{F&74z~4IkYyxr4 zJc}k@lA~YMbT5vfmo*DIT8P~yERw2&_3&sG4Abaid!AT0cR9Lw?3R#%4oiA0l0?3u zm%3@}c!U9vZmeD3nawmEoAkiNNQe9!eVI&|#5u#UoId>^+Cb=)P4Dw@;O&3fSCav!Oo%nI^mYjY^NnVO!V%d=#nOjrF zu5m=D%Mz!g$0G;$S3FV`9XjNUI6mXUm&>0q_uHqLvUx!q3K?>fPFG}QOlt&Ttd!7y zaZSaXIdgKUrEC4ARlI)M)TxQ&dCLo_E>wDZ`|bYqt~DKhXxOGWO&dSEKOB}KVB5Bd zIjYIGjxVnsIN`*i6VnS_q@7kOD zry@xUb+<;PP8z;#U~8%s8C#`cl?fUV$YTU2+IcMW+CAsqi(7Dw@3&vLutK=;YO5pFPRYDVyV3O#t_Ll=x41U@Z36%#6~dW;Ed+;z zsL@z*JfG}vGD0Sy!S^9CMJxIkU41v!BC!udoHFT(j+yO|UIs`C45_99tb35mDKKro zuv;C8>V-eXu}N5kc6cOVe+x>7noR*clBj zS-*+c%93=WV`Ejh5qFL+9O0LPry_u(?i?q5eJ2~CYj6sz)pEIL>b8Z4hhHi`zJBEB z(HD?QYB%3)L#!7A1xW2RoUM!M{b)`CWk2fOyYYEtcE-$#j@r=#jE5j4d6KcgbMUY1 z{|&_p_QoYQfbvy@O&+R3!Msn*g0{D?u$1$MV-xOy4Ko{pGTMAJ?d>>Rw5UiLI82_1 zrzHXJUxVm~HYbFOU2)iKtZW(JC}0h}xjd7j+Rn`E__YIKF~wKvq<1anYj4L87E>;E zL+0H2aXAd}Bbm%Sb$$GL!^W#+ zIzsOe0lRVd+O_9-3ZgGLvGj{mRDCQPMS!(u`*>FY8&%tP2u=mMC25@()}IDO{pPNnJ0Ha_ymy+r!npOdev$2B?G7-h zAVOB6srRSbDNaUA0*`+F&G1(Ro_wo`?Xar{oQDDP*H$31EE%ht?#^+NoZ^ogGtfP9Etme*lf(?YZwj)M~A_+%O3EjSC*( zE4qTC<~+N6+uCCd=woJDoY*^Yg)d+OAwqEC|*V-sI>|5pI^ z{U5!ds)sRTqkr|j;?SAvv)A72ujKRRa&r|(H+TERL28(EY!L0a;PowSB30^v2g6HG zR`PtGzLSA7yvp`_>OQ#N#e%wfPv%h@Z0clh^`#!O?(~tpW<0&v2@|=g#GzGr=61pa z16<3RvH1AbAXO@yPOu2ibD^4j7QZ(jF|DNg6b5*IR@Uf?ul4y*K#&-oG~vIK1-$aC zDKMm8Au379E$#6om)^ro9cLa!&1Bg<3Zqnp$u9YRh-2{u@YmCm_rcKELaW=q|A~uD zn&N&mmtJc!qdcLx82R<(L>L5aR(|KBLz7u>_aLibowK6 z?k{&8zmlZ}C|8`{K6cGRmbp9&h062*K^Pburdn0lUE;(m$d~Am|it3YBxAk9~c_r@OVC!df?Pj07Gsp)D zR{oyyuV?k1E~HtXIl6$p-> zV-)vODme+L5HSJpJN(2D&^pMXx~;dYzszUf&kObmUlFi8(oCvbu>E;=Gk^`CW-B1P zgxHC7n7@@1!{aJ8`r~(nUD7ZzJ?$s~O#lS%hC4V??{a(fYA!_v@Y1EFwj)b>+F3=w z|HjC83{mw`7n3esLg; za@p4R6p*Vx7IH4WYCFI`2;VPh(;6hC7fkL*K_A zc?tN@$SH%8O;LNxqApH5N$$zXY9MbhzJ>toMIaqDMJ)A!YKr@s{eD;lk*XFExg;g; z+EWOtGE6l`Uq5dQ)xIQwU~>R`jXs*ukHm=!K*wAC;pY~*`pLKCJGiJWFDkqIy?N~Y ziDUoO0`w9i(!nHozbm1ZgrQ9<+cV*6au9xoNdMse!~$gl5wF z(z)~J)mz8al2{}i2iN=L4FA3h7JRfjK35y3$gm|ogIWI#NR)@qGZ$o`yJM7<{%N|M z3Dp+A)3{@Vn?`XRMz1~5YVg_vT#SRMp$elzwHR=0fb1uFS#<83j>YR)MgI_|}=94kK>BOjA z8f;CSyXf768j^N|lc!`L$Vp6@kOhJL|k**+ZMz02T zjvgvD3Jh@UyD_-|3q(kwvK2$G@oF#%j?N13x#Cxoe@CR`Fso~u9U}Ie2LP*~U~cfE zPUuTakX4ybQ&oVU)!=H0sv94F^sC_jv~{*dZLUe`q)Va^c8RK(eeZ-|-3rk%)hc+G zZ9jZCOFujL)_1bt2g+Zl&^0w}4DF!u?(Hj62oexL>4RzMJ-ocm^{7ZIc<{;C@gog! z`>G?WcxK`b0)XYSQ3il{H4)<%+3lH-(*ox6JePuGrgw8@dNQ(De&?uu4IE@ho8-EC zW{KnjI);qcwC?^?NSH`y(5)~S%RG!ZF2hvtt7OGvL?_(0}@L4RJlEmgr|}G?bhmK!>!=opjnEX~bo~duQASG?k!mFMX?} zY9Te_x+#`uxkW_>P9~eQCu^ZIJs4>6>-N?Sp{UrGm?)0jL2jKSLu0ZSAnZ-McH1w{ zYyao8F>Y?+IL<*5^Ix;HkvW>-d7B0;A4o$Tyf*ng7QVH3>^d`|?lAc+<{I<|?HF1Y z^(pKkL(@U%P3(3pD!P6>kgG}D1I2NB_MFSllNcK?#L}gj%H1UgRi>DtDt>nUoHi@0 z6K%EJXc9<9r9W>Ph)(9*F$#ANd=h(sHd~egF^0DB*iyt3GBmV1XD{`;oDghTHoRD0 zR1Cx~^EadV%;Uj^TIplrR-is4q*2?ogsgh4V<(*D1v9!}WKxL;rUl(MYstNXC-8p$ zoIALk_;|p>K&-K2s}*J1QH=3?wiLkCo6oPyQ!9 zhMjaC(*hC9SF(DJ=gXbx=fMOys{}R8UV6^6yU;<{PwMyTb@<{V(nOHJZ8u`~$;wwzFMp?} zQLZaQ+d3vHS&2y@r#b@(CdT-l?EDqjh3R)b37WTY4}0rJ*WrZWVrztn(?xyV@3;Ft z8ka@x842_Fb@m8mIvSa(~KZ38t#$hOxAom?~-!0gYkG;nk_LqOz%*52yK_=Y%ZBg~eq^n6J2o*J(M zt`xirF7Zv;~s#xuhw z#v#3es;P~|8bK_C=77LNU{@#zn;W!i$9BLf@6AE)^F(ZS`Qg_sl@8eyh5pr(8QTP7$F-8d0&f2HI%JChp7^o)m~Y zV-XvGHxD+B75j_N@TtNM;B`2<_so=$?CmA=HQd8q-vR!WxnM6sbKbshBtsZWnJX{9 z{JEN%LgE?CvzUnjL&(GkA*~>65N?j0eC-=EUJ~hL?a6lltOu`M+Ysp0`&HelvFk5! z5oH#fDOLioE`!so+hF&6)Pg++4jb(p8s;~iCVh9A$cva2CDzQDj}os1Teg4wlV~&{X=Ezz zu)J|mt-K2tCbP#(PMWM05k^(|+6z9uVnRZKmZ>mMg7dsFfya_2JGO>2&}-j5#ePV_ zwYz^YNIdfW+&#N?jZP}uS$Wmc;psRTywzZnSsugo?>rP)0>eTy4%i@QYf}2d=O2yo=P^ z{;)zf(P-}HtpA2A$=uBk`6ME_cGPT=ghftwFm{> zdi4TYRHel&#LOpYva<@cysFf?BD$p-5Ud^)ICyPIsy0SjV0^O8X3UWpO5r!nwB?25 zd4zMGyRmPv(U-pM+gsmoPr_3`yWh+8T{b(GG*nI57I-ncRl$c=>%Z?wzgokngFN@h zrd=nscVlP*I{=0{Ag0LnhFsT@sfRys+T1ul~Bc^f0_1--42ADsWe#ZW;t?s zy$gZ~5y_~bhv+n`URJNeS8Qmp(mPW_^0tlX* zS()g+0fP(hfel9AX;jaHIw=&)zI1W!Gug*S9q57QtG@MwAH+5~?9tD(L!d<5xI&VCdWoF;LJKVzE!C-%j6LO4zaQW3eku=m&_)M>rj zb}@4JILnRit-BJGYUaM_ep`iOu z+@ts#>-V(mFr(u{TQQm)^}PvoCe6Pkpn31R>q*zxhwf5KVk699OhOw|S#b&ZYHNy$T) zu@F!iL&~s;kBVa`b~YMS8r^^W9EM1tVCONq>tpswcD6+$#4m-rpmV9@v`k*w4;ppy z-Ak&uOz#Hu>l=60fiP2AL#Wn?Em{wT@zR+Hg7bPPwC7n~Esakgux#N0pV#!JV$LE1 zQ{2PJlp~fy(*J0@x)vcmMq6QRW3%B!q3i)8BV`V*SN9R^gy_m<{OI&zWUr;4=ahb( z=Ixy~StSLCy7BTKA2-hUiUV6mM9xBVWWLxTh0&~8SAIkqCL?JP-Bm+NQtD@r0*LHk z@JjYaCY<>4Y)gL!^IsuDL2TYA5(XFd_SdIK&gj~;5y2kjFMZ^bYZNSPqP|q~2B;`q zu%PYUU6T(?cNwKUBG!K66xNC%T~lwJW4nZ^`Q(>pEtyTP%clv3Xi?I3)}N~`7fSiW zSQaS1aw8EuY0_k)92gGw6}H~i9cZdEy;)e(@zqP`lVv+VX*%`M%;im)eE-{SVN2tQ z`(00tOnvgUVCCMOyV7Q4H14$nutxSYNmC%98O3*M<;G8F_GH`8U*BH;!P=)u+$m$T z@lQ!JUaC660K!#y0E4_z$RGpO499&^SM{<6H_ zlFEP9j#~Cc11XKrjSk^$O+wN8N>N;#&@}y?{P0)yXz$w$Tv~^%ODt}5J90&8Xsjzj z{;gPsDmv9MZjXr}HGd~(Wzmw5&`^OvU29lW*+ogQLsfm2K&}DI;?%MD)biz&U3IsfsHn#@2`bBX)FP z5hF9m@F6ta!E4(e6(tVS^_LI1#16N0bzj)r!8RqEMk2k_CuFKNpqvVjje3$ByTxyb ziE-Y(t>4ZxpBcAzTZOI1L{pZ3ai`93qS@?t&!(663$DZg_JVSg&w`HuX=?RzilE)c zH?EUOvaIRx_4O4cv`I}<4pBct$Gx1kf*Y@388KPfPLY)P@fN^7z5|W>P07J6O_bWW z0^{N$T48e-K@=yM4qYh*1v%?ytStK7SB#{>M7r95d&>ez7INs|79iNdh%>*;Mtt-) zds#%e7-JSYFZj$hEI=s|#H*}Z_wGi{pC?b55~74rb8L~#Z=^ERQs=WhBzHiL4MBQg zqNUy(S{q=X_4ubuL&^d_vF>DWRCs!N^*XJ?eKe?;2q0oID0*jTpUpEY!reNBkW$Hs ztZ?aS@~Pv*&)d_-D^h3uny?8 z19(+$9Q||T>Jyh-7KWzmeDz`?;D(sK?)m&0`8>ya73K1t4<(=>uCuoMBu!;nMof#__-6q(Nd)(^^Z6IF4o(IOl`3)k zR%HvauQ5Hga+f$7Vex*Flt|oE=RG9Btq2{!BoU&VP?_Gr{fgEtm9+~(lhN;;rd3S@ zH1RcX(&R6eol!w`o6NySPG?hZ)Aap0c0250C}mth4Am$c{sDE0DRU6IL-+4-g{;ikfax?$u6$|1uswsR|qwMGCQ7_NjsJ{Z|Y&P*yK?!}B5YfD`mg z8jHYL=wV1l_u6{&_I_=D5q~}gErwf+Bpq=%#wQ)TO!ufz5Z}DjmlJb}h#o8<8uQ>u zWk2r49Q>{6oYxy^fqFMr$Yi&6zX9UngDj?IhtX|d_+;_|bpHSk1>5^g!CJ=U91!Ur zc@iNYo-HNDpqdI=Tk?RX=fTh>BExZPYj}D^$M9irP>=^QQTY!fQ;2B8X(#dq?}doH zMREdJE=yhC;f&QgO}~ILVd>8=&xO>u_t&?X7$Oau6yJ|eAWvh*u3fYpO6P!@iM)AZ z*PHsT&f}v;e0lY9jE2G6*QI)?fA#cDS% zigf&K4I0bpPReL2@N4vS?K#?xR3C!tirnB)V55N={Th}uL7`OA3I7#PtP7&sU`8SL z!i8P7BU(4cwVaZWa6Fmcw+ZAqFmf^bxZOMKMBhifviM0t!mvarln=)jp=LaB5mBhs$;CO;?mkH58EEDfU%O;iw4^f86St^Wq~< zm?m|?kv6fu(RQL`r*|HG%bH?$RLu?<6A``0VC4S4e)tQlN>sugdkxRB2LGW4?^xzy zWEzXp;R(=Tc_Dovvgb22*0M4KrEk5~t6c8jnka3K42B~al4q&Hvvhq6pY|D#b=jIm ztbrSGEgNbld$hzd3DlqhhIkTLg!AGYxVAZX3CZ#-#S56BPvL>hVYhT1AfD?*_tFSt zsSgUHz*(pA=n{~T$;>e?G-1&4wG>(x! zEeVo4q%8GUY3EWmrDL6SLk)-^6UchJL1MG0REW0TJC`vP*JMY7p1lV0P@{k4Jbojr zJo+4E_1CeOh!WdBzbPM>UCCk(#q6@og4HYAETFXqSx^?d$zm{eb{sC+`tj}K$AP>| zrM1RYgXEip!iS7QQFcAzBtKg5+9p8N!m7li^d4_iUwplMTcyx2)F5n$LSBMwVB|uI zdpXPu@m_fU^is>EC(f^h@3_xg^?ryjW;@Q7mL9XXfVE59jIl*GZfv;T(J{uw-~R+~ zL@VsOfl|0sTK!u50$g1!AF5hZfB!Hd?o2&eW7?rdTweqng9XUZ`q`{`^9n^hqxDn> zR9nH8NuUsx`q6?I)0uU>o^+AAYuYI*Tef+SmBr=qH>Z(lR5$enFRZ8RRKs^hTibxG?>_f^-S_v8-}Sq`UDxOOIJEbE@7J)_b3NB{t#uz^qv1l>^Y739 zX~^J|Z8WPf`o6-%!~}lrpCMP;+i21BS@=g3BT9jv?010GgFfdG!w+GI+1qbqVkG|u zQW7{U2y@1a>I~sCGix8mkr<*@Bc}fP`uIr3v~#OBpE`A_S1lKGH+3+$Z6Ed`ie=DE z+8>AYAW<)1-en|&h&!i`$;#qPFoc5+BO&T>aYy|YXjBlbtix4FwQ|qRjce60f^)$Hl(x|IXcf{qQxg`CkmNXtMUnh;op`LSobCEgB_$UCYM-z&qFABwWXK3%ioYB;`H{2C z*k&unR%UfxCdK!>prDgmRd=%Xk-1~6Yy5%+luQqLc)2d5F?5_?Pi(w-m{x_(%E@NF zc2D<4>K8UW7_bT)4RtGBfH|3<+aX!~CFVih!MY1a2mww6pc~OF=ENIY_ix!dPF2*9 zMsPS0nL#Xsdgsoazf;&{P4g$WW6t0ZhS@Zy0(u?tD|n}tv-Zc`+nKU@V9cYGi}$Zq zl2M~2Xj>B0SLxNZ&X?8;7Mn(PT#L4Z1bR=l^U2v&<6n=|jgQcd>EEPAY!ugL25sPk z3r1teDW?R+WtT$qMt-*>O$TEQm%^?-hL`!=n zP2M|00U2fO8$z_b*;`b@Iao ze%h1T9Msa%nob=s1A$seIT;1uQ$@~+m zt#`D)AO2&th0)j2X&5_1Q-)+3r0*8BGz8F$bsqhCu9GNgy(-GOFsDn?{`J?C7Ud~5 z47Oc;{p!^Q?5GIu(XTc_aK7_yD+xZ=alQEbKoc>$6;A z>H%pl`0I?5=~BFEgos^p)`?LhCp?(cKxc%LbbUYAp^=U)1t#*JcwG!dZMcudCTiVy zqn+k|M6`=pNA-*(6X_`zd0u7}mNjZ3`;P(<+C;0J~DQFMbaypE*z=?L3OZQqo+U-k7`G`&K-$ z?7mTW>gkr*KL)uxGLS>hx=5y|2Erv7*7U;Ie1HGsX}Qg+v;ZD|QU|kc&z`2Ve(3Jt zTYT-z?Ob=yMCaCV3xi|dF8AnlBR=-*Kr$7Q@JFj~o~ba|C+MN}!aeV^-lVAq%Huv{ z8arjjkJpzDHJm35`ON6L&bd=fiYHhU!BQ6 zQqt{GhW_}K4{yAWHah7Q{HFNF-i&GXxu*(}y@Cr59;sa45d*;tk%yYo@e5KiU-LQ| z`G5EZ0;om5DDC5DVmx+7S9iPIm9|T!*k#-}b8h_Cz_`)FJ(l*lQkn*&WD-Z?ii+|@ zf~DxYa9$)dggNV9{jue;`0O6i=4jfv$p>d<#HVC#yx~7>gma3E-TmBSxBV;9PBbs@ zyjhaJU`+D%lI#UO#taZ7i z*kD6#{-0(~GKo-$&3(;d=2gCM|EeGN_&{=TN!(YegM-picGZs4JraBCQ!S5gGvg*k zefbdZuCaYU^pP|z^)YkNF&k{P*-z&ZqqrUC&D#v6@>}boFVb=T(pI zw?26;_m!*vpx;Kn{z-JXF*33fzg{!AeFCcJ6Vox#0tv|zG-}pN+byDY^ny2TE-@uP zrde4js859-358sw37*Y^zrUxZ_6JPL>?)>YZ3LSSx#FT-zjVEm)0?fm5{DXE=iVPd zwZ_APe{YJ}U7WILTywi;MhOk^Y#X_u)P>XqL&_4!|3`)x?Txb!`A`<1^RQ3Mo9llj zmp8ZBb9H=fiN&wp+f?AG#cmrdT#Dsil1O6QnX*_(rtR{qf8DIb|fV_52Q|M;c1rwQM=YZd}f?b5`XJap&5q`$t)9xyxFZ679ND zPby3gr59E=bS}l&W+p1MU$6?}w+fGDx0(;7Upb{jHu08blxC zNXif;g3?~JUdfO=k*i=eLj|_9JlV_c_}=k3=ko$5{v7Y_G1O^6F=hi3D(fHtlWw_F z*GASug!rv>w0&HlQS|EQttHv@0}fn>PO)qm z&~4nfK08yEwX}Zq_Qr{K9UBrC@#~JH@RTJ|zBjbX`rSWP+3rJynfuI~PUAgyeLH1p zvHgSl_UP;7-*q2Pi!Z9sEuWM-dyERGv^O2~+gkIk6p(R~G(v_X{A})N7yM%Uk4nFg z(QVV?-zMCPTR48rle=kq(p=o<+`O^M$i;5^;go;s=RRHTUZ=C}s#YbfuKn@vg7~}R z)=_Ebh(*@Ow3R^(l=f3~@n=sq-4OzRo=ae`cP))Sv%LgJh>;Hhv^IJ2{*);K`S2Y za6Qt<>*SB0lkV9%+TZtWd*i^A0H3v(1?jzt{^k7r`{SLK{Fa#VD?jk-_4vmN_k25L z@ARR-@ND7z*_9C~SEoFjnehJ8{etfo-V8i<<7;C6^>Mi~=jn#Hstxxb|CDxh739)v zXKNgW3_VE5Hu!2+ui4YeybAW{{90xAt-}YWl4o8{-#TQvCx31he`b+~ezJ4dgOaIb z9h{=-wltW#BkOQ}6mS(kCPOaZ8AZ}fOtEA4?x?I*B^567%fBUO{Fs_O*cF_-6lPA@ zMGYy8Bww3s>4~C!eWCQjN%i=QtW4_M#QV*O0d1Twz84>u#LFiy@w7I{!A;G7J9GX^O2r+b8;jKf#a0sr_4Ig zXdQdc_VlLF0Y~+M2*Rbq`pT6nv6SQIZnUwp&o=UOS=i-+(He{L+9mJXUO(eyGo>PK z_ntx%kFW2FUw*Rtc4~gP!}m4n>wY})ORd4C4|Og{YfR}_+o_?O-)c=yD?{Q4LDn#P zi8^+y`@G$7uO{M|tk55gcxzg#y1zg_L`SJI;t<$DdH0f77vPAH0ifAEcZ zvwoHUcsAnrB*P~PIQdVpknm^bcCCh8u->izR7BcLj!tequw3trzji~XYYnu$_Rtl)zf8`cyS}&_!j*Nt zs`J8|XvYjw`7-8Wi!UPxKG?y!hE@LHZ2l6XXBk z)!@<*s$dM2rA%X>8n!*8=JeH`Y9t*HX;W)(dfK>6Q|N#NgRp_9U`W&-;a8$(`ShUG z0I9fU6xWQ8)wz&Q;bVOibA-pzQkNu##LOgb*ZB^w?nD0{Gy~+y{-&^n8pQ^bu0jHa z;?1RBg)6}(bhFGAV?&S*QT$pTxzXQJtX`>6t+$T88s13VaMBP zYu5!$Ynn9JIT>fYNoCzp%Q*a}R&LlfpBs1~Z$x6$Zz<`NNhf{BZL&`EAJd4wN+yz0 z1r27Qx;C-@r-%YLrFmOZR!b&ErLFlTVebLMCzrS||I#LJ9nKm>q%<^@9)l>&hm44~ z=IN#Ah*Gg}_N^#S>P-Sk^2S{ogsm)ne!hl`-6d(%ZCp)+N;>j=fgN3|w+|cMMZ&RM~r9>JCoK#0Gi%*FDr;Y;)em^tt&{-*lQksaN-uHW0sNdqnDM?$)P zk7f?MNEj;(>CyPq5ZU+k?F~gAg7QN;z>=My`~AtRJH-*JU9%w7KXH3BE)PZlKV(EF zEt{0O*SOLUiX&LA8=BR&kq`|G4CLS1$1R7!zDo8~hO8V6*AB*-NyLi-madfReLM7_ zv6W2TAgW$RXO%2hXXN(rPrK||?q#v*mx6UiitS4-UOVSTM z9ryD_;MtU$Lrzf?Oh20*%%PAp+v~o`@A!OC4yxswZQC}4uBHl16q)z#*&Dg^-gzYB z+BMS^D^4x&^reOmxjmWG1)e8Rb^iCn?-FN&T7x^$-ESR{bwh=emx~bP`LK==P;Q_Y z#rKonop6NJyVwjw&6AG5l>QPj`9Y~SOGsGfYvxW-&F>6ymBD3*`_sub{>F&4gEQ+D z6K0UWpqiJu^WPeG9+M8qDyXYT9YZ<3PEV$Gvau(FcSL8kM7-SgaI%}SK`_)zr)$mp z4#Teo4264v_I&cv1y{LjtahnQ-7G8E+zT$xe}OcDAjx{CFv%JDBka_B+J+ ziPQ@pjjW5DYLDK%U%EZ}G7-8Gd63haiCk3>jZ*1_i19?ygh`W@R;t=W#59_Jj9X|v z_OB~C;VlMLoP8r&C}G23RMTObo;`cUSN+4JNkIDmb61#c=~JuG4rcTEzlkO?%FDfh zu1*8p0g25T`syZ^n3=M?8;&0BE!jU=30-7aI!7_P=ZVcle@Cs;A)1m5?|EzN@Zq%u z`;aht2|SUSag25sw}jfIA72c`82m1ZjLMlGZeNT`YMiz$?cwB+7bm;+F?6@p-1Aol z(;=qUCLig#=a|{m$=PmWYI+%2`1IA7&^>(D#9fp2%?s41-hES8Sm(`?qGtOVXfEuy zu-*Q`?fX{bxHkQsZv5>{N{U9`{Y%5$hh#p^>|ks?mo<4Nt%c7wJh5DX>ndB z_#A3&?KvP(ORFjPF}qY;XYk!^U9Lz!Jdy(WW=r*E9(FK*6x`Oj-|of-HL?)87*enT z1{lp|<}!d_eAfzt!-=CUEOI%Cyq^)(I}V7b@=F%hTIXu@X*os9KeL0u*hwU>3PWmY zHfwgRZr#f8h}CHtnsaaifz)duN@!fNt zt2~%HHNSDo5E5q{cD{rXzaZ_;|{51x<goe;0P}13kz5iU zIW!Kuh1QqTW)$pn9NY5w>R=vGcU;s~bnFS#vuOA2yEo5Uf5=wvk3G!qev3DC-NW2R z%jPi69iI7 zOiBrsGOk`7fv{Egj#sbLh%y>Z7}9%#l!Ucw&8s zh=Z3bU%rQ#)RNTa$1Z8|LpR+v7XV$ynN5oP2JNUd?uOp?cC^ka(XaOE<;!r4M4+Ye z;AqY?>QmP*f^-Ny;?2SBQRA!>K$0Ains%`^m)(3UKm&U={N6lFKq@yYhp^Q)X|i$l z1p7B!8wNJ*Wmshb8?V>D|NguOhHrnkW?^gc-@d)sH^!SX_HWu8nW!gJ4du3U+d3=!|5g& zaU{2j@VobkadPqHazAkY5k*~}bfieoE8TDJ-k1?>JceK_eh)Ow-B+67@ne5L2g`cm!~O)m4D78V`gn>>C0VX)Q$e}MR`*(HqH+Y9W1g9 zT1JmZq6uA?2QV1+=qhDu5mXlDPpb}m7_Fsi+e3Y0&Nr)BZG|IB@_YS0q=wVL&z2ZC z(0FMSLzZTl#9x|pZuMy@`64kEbIBsMKw-3}j-CkAj??e;-ILS1@{V~b`1*bb83=m# z>ZbD5zpojzeh$-oTJ)T;PU@MBsl9n~I=9FS9k4xyofZ#S%N?Dh>90NOu38o_kP!=AE z>y!~&TmNa}$J3DVKDO%HLiruAg>_j8PNpEht9n-3%I_m8CMjL0rf%)Q3XMygKRKdu z{Lv+e5oYYbJd&53-Cn`f750CB82@)z0K6py+;g$3S6bj$VmMQ{>Q7z+smq8*T`Ycu zuRCtmtO)5=Xxl^|xL#6PYG-f1n^irP(Bl2*;lnpDvJIPM?D8yi0{xVtb}ep;7c9jK z6@;|=LPO#p%Ofqe5BRzl`xfF=-3rwhxe7;CnjgoZoK?2US(_9{I< zJEt*N>+z%*N-sB^#sIwIR&A3ze)r6=jONjkO;b}~kzWRM;uO~+l zKseJP91>^8fffJO%QluzQ8;v4MWL?zXfn}lC6%?as)7ZTGmdjz)YSh+7d?#%WF~M_9 z>UFw=$+V-FE5i_1MU7Lw{h^h=uT}oRsEAQMxj4*H9Eh`Q=9e!ygqjv}nv0=vM%*VC z3Lj`u7`j)Zetr2}8Ll~?EPq$jQmY|!5wwEGxsS!NiyG6sYH0>=WaKA^YNbJ*j3zna z(A7CRY8$w7uF3Tnf|0po6asrW`BYSVOAER^xaVh>oCFIgrJ9HlRJnS;hqylWa%0?P!v*m+Pm4V+JPNN1h?iPWAqA zqJbnLK59WS-5Qwhn0|4?b-Lvu>#bUr=DtxilpmtqzH=mhm)k-*;Pi zR?=r)N(_-g@c-k`~#z%%bFpz7XrQQ;{V_DH^>6UMpUgT9wPdmk^ zVS{ZKhs)Bzkwo>jTDyP1Dtke!(w2)nw0i9yXsXx#Nd#{-F?GdZs;3i~H#QDRC6|`^ zF)%iPmU=dT1WLvBv4BzV*4f5AuHCs~P0tVxmY%WqDJ7#iZ&ohgH z=|v^pJGfftI=Un#qS1>0n`NNwcWa=0f1|4v(+8d=4g?R37<^p*u2vk@&1iXG9q+X? zau1V>2=!*d1bAu;qo82+HeRZDZbT4ghzR*?$ql{YC#R1VwNk#{0>9wPGY;>i8zVoC z*Zn#bXGd@M`K&*VTCxOmwsT=Du`1*6FugEBpM<~ zKrE@S<7Ct$@t5;hy=C%r~7lZNS0 z5DJWYlcAqxO9i$8J+KhU-gaxD&^%2jtjGKUVo4(`GC$t8s$M%(o4rI>l|cGfw`oy>NWchn_$KEj8aSXjgUuaG*lB&Drp}uR{3OIO;diCzmOr3f@^(66Gg#SadL%k)n5c{Hth3o8mXV<1AJrBoV4<2^1%PUzqo^_%rD z#ewz?uA`{+9t+PjpTJkQgXfzlfvDnV(|_8@S5avE4I#qJlx}od9|IJ>%QENUF-uX| zvR^&q^)sM|K}2`a_S!N0Mg0iR)07T@^SX&E5s8Up=0w_kZe5gsSLU6qL}!VE>&_SX zm`+}-l-^hwj~`FsI;(dQcS$MDBs%`vlZ-8@-W{-6kfJ0SS%8~*f&R^-(K^4|q89TsQ(J;lSct{>1mQlo= zvd?2wN6|Y-Z9md?K;AfGmL5^1+Q#drD^_i6{T2pUNTLM&$%BlBW-HE1OCyaO4zn4g zGC_)y>8fv{xG30$sG*2l7>#-NXtrr1-R|d6VQ8}QOH5IJ#VJw;5umGRHvAd}OMO#M z)lwg6&Bo+Db7A=86jq6WFLZzy|-&9S{pAJ#wsV#J1UfrcyHB1oL4XB zjHuORB`qlO@@-`t#>41z=rEMzjWc7P#6*y&$lk12U`3m3N_LXDLB;f2>#1JT_uhk% zwefS=pKO!#*e6M3K|z%*7(+HO9>+_A=`3!HMVIP_{*rS;F9Jiaiq*y@CV}dQS*~6Y z??2N4elVD)S==c0cs_a>LV?}XexefS$f71Z!Ro{SWQa?yJ$?GLYDIoiuZVv;0q~qZ zK|&aTA_)1F1gZt^-zU+vlMz-KZtWFH4gy=lI*o@(Q(w3A0gkGhZd#8hNkXUjAmB$7 zYO^bmpte{bR|^xj7;J!}Nh9w7N#&B=yf5#xk@bW?`eic<~Mm;X>N7_yRY-|mx_h~z}irLWWv;@ns= z=rOpBAJo(v8`e#q(rs$0gMfRo*|sMZOsKlR1FKHG52$^dS6Rk1w|_6yBV{|rkCx#2 zxiQv5!Sy!I&T%h>C@$YY-5v+Db%w?+`Sj^Oho!Ol3oT$G(JnbGiOgh^CM*)t;ERMf zk#jfu_WoFGXyEOdR%578vc>jshI*(>s-lge>TSjlb{dcw|3#}yb7p%41qF$HW3!3^ z#!t0o1TNTk%$({yX5mW!D9K;2nemAHsy3>IdcVE5VJCJGY)DJWU*&m~_uyK@gw(28 zQ)y?}JNd%d`xHJ|GGli_7vb!gd;_ z!OGOsTY6IMYi$$V$EBO z#5WW_JQ@wJnE%q?W98e!SE~%w#wsiG#E+{qzWXokYUGI%DYT_&@Gx->*K%7nLC@*;bj_M2cJc+cl6kF1^ zV-&5}cflteBO@-v7qE{Wdf5c?7IUhvFh#9$htd`UH09Yk%6AD>s1K6jTO@h078IT! z3h{@a0u(t@K_Nv9h=>IG{et9SnVy7`y?H}Cv{9NKD2WsmT+vo6YjV4^w!E)qjnTWi zTGQ#`)KA-b5DorB{G{(+0avkFtJ2R$B^;7GqONhhTfj_dTWK{zV z@9G!osetqIgNO*O!#Od8P8pQaS2KoDT|YjDR3-pvGxGALNmNLvRAj5TUzS!`J}4MG zh<%e_Onx+~PJ~scfLZEm1!Gj!7wD$PMnHc+TqjT_TFqhIzYd9i}G z8KSb!+JEw8?XYGaRxZindODkE9a<@qda;%|;wZQNt$f9yA!>_Zy7P=jt1qCS7|t`1 z(J|(;|Fvk*BI>dM7&D{BRg3@3K&)a3vXS;CV2r9<%X;t88*3P!>3*&9v~<2Z(0}S(Hi%U6hCmvo`RxA!mER5UEqp&xKsyf;w`w&sS~*=P?_ zFVb)c0nj{VdaWY(SV^2k^SZ+=7mjBq0}znKe73q7jON>`6(>>~R+row`De?OG)c8% zpjq~2@1Br=CZ0czp>_D2w}CopuqXQaDVp-B294 zxSQmwZB~szb08FY4y3x0pzLfl7eTi+P2dY&y+Q;rN?3PhI>ghrRR_04`lC;<>f8CK zExLCjxyI1c0eki=fBcx*mm)a5m0#|R*mCIid-~lr^hMUM83l6N~8T-!6la$f2baT!m`uIEpW550$YeQyH(M`&4b< zQA$&}Ulu2SM9w?Cq`-|CRRP_nJTh&*z=EO-;rY?TT)uSaHKM8|uCCVfh0=uQK$L?s z&UEX%So#s&rEO9iQRo+QOV>PPZdL2#-yZVJvgr~|ikm!>!oU!|Q zJV=#zr*r4w;Fd?HT*E1=&p9-GC{j?J9zCow`+wew^_^qV_!N^q_tR=-QMoI}mF1ZS zKYZu0?{4Liu#^b|3*{E{Ho zmH%$;GG@+&8%TPs`I6VX9&@=7Q09tU5H_PlR~3iTx$1kJgi`p~G+};jTqI#91nTX@ zS|2~+d5;VA35q~voW+~FlSLLJN#%-j-np}MgzP)GZbO#~>*@(nh1qdhv?!U&Cm5CE z)+<=)`xU>dF_U%^(t_dQ(*%QXq;cx&Nu`b8rr1zIe`3MIFg!&O3|id8<8i!w{>zsg z5K%CBX$%s$sHN6xk1cp;12w%1?jFSaVWXe?~L1p_2Yg1|=N1RSciNgzX=QtN|?MT^d931u@So34v(DlkE4AoYz zl4c5&*1LyCM-X58`1;x}S#ktRB_F8MuAM1`IYLHqHUk0zBDsy&AZ=`fFzNJR#}#Td zYZimrL(I^ZJvBA!L9B8ehz(pA#t|f33GO4~{Q1Gsdxc3=(A9G9Af*CtAD<{%d3w0T zNm$197W5*O>;p=!b%@G-e`CgB`7p9>cR8&&By!ni9xELRM}Gd}-PgC5^ifV@t~gs2 zgNG@Lu0X;BWmb^%Z7F)zpXH-QjXt;20e^f6U^vD)Vemgu67#;)BvC;k*kEo za$@j9w$YZY0m~VzJZzscot?VO9}oeNIFFYJU&v-8Qiu7P8Dmx;MvLeHJ6I#(A~2!^ zh*?OwbB@m+4@}r+sk&>mwyNUrP*X`fuuQnFabv~^xRwNM+4t}H4ZShqZGQA*@d5|^ zK@ZRX=p5u>k_CrWjc2}dtuI>DI$Z=&1?=CSKyuavY|49Oqh6DEnDhLGK92shXBXl^ ziTJuTLg*C_JQA-)n(Q9fFgJQ^+xX@Vk`spmrcaPPG>I0hl^AVUPk1`{F|9UT6>YC@ zB!s=zwot~e;dRBnlw382gJ3dC_hVNFalE0ilc@{f%oo9E#-T8&&>6;Wd~?%iv8 zhR{Ykj;yXHv!cWkP{@p*{Gj4edr9;^PZX`ZV`|L*ruGPuY~15h;g{jk`aAz zlD+RrvV|6mW+O)Eanwiw?&L!_q@N#?YCdhyV1Y6@hFxqqdq+Y!A={)V0Rpn?^~5c>sN1STzwO6z!Ec9if`n2dFNp!(MNf$$gPF8t zk457rv(|N|olBJrCF!XcD5t7b^{iUe!Lw(-sy{Rkcr3nJqi)@6gXUe$&CPXtBY#EE?~pQSiw;44&8yj2t*% z)d_%?^qi8kH%G!xz0`}htCre(TL#%_a5P=iq9FqH=z!m3iy81#qd^0EN5@dC)_l8} z`)E<%^5D>4USEVvu#2&Jv0-!w518TB+3^Y2u9Sf4+2Yv4Dlcit8;u7+wJ4u=)p zY`+xQqBtN9H~jd;B{JiNx2D z6A4PohnfT6{5G9m$65^gnPQY5Y_VGwPYd zShRUvv49!NyQMM?^#Pk`Db1$%!r^rOs4|f!)r98)DVY>dNHZO=CxF%f3b812DH(g| zh5yz{M*jMM75uzbBBR)d;p+-Uz(VS=0)Qd|zLy?1SHh-aG?Ng>PD~|)E%?&*;E?q{ zU9&z6J;+giT9R{^xRxSc5nPsiILhn-Ng0s7Agx|{Ac$;PC>Zw*%}BDS*^Ls$kvfVv z?!e!xZ=HAzHVz!*bq>-siV6!M+WE@PPfi`KI)9B-h`=#Y?wJbAOZE}aCizM6{~tai z)9p1zNUz>o&ho|u+y6-ApzFW*a0^@z5f5%|ZaUtL*>c>1VVNqz$+T?8tK zQzr?Gxv76Y3Vp-ePyb#PN|@gYrJaE_vnZS&9*L~7Uei?YG~Il%*AWZ2Ejqp4ylzzM z?YCXK)m{KxQRrnk5zl#Alm^k&FWW3zc7l%6AznUK95vy~xoO~_SPYcFavpJESs87M zklW0NzP9A54*p$~Sw&;w19t8_$o_~!0JH&~mbkm$ zs{GWjZe7Q%iYI0aToC%5(kbBzMGFG-`S9JCuw;pwn=Lj;TK-`1EU*ps+`ME3r`yLh^-h6P26U18* zWkO6@!#JqY77nzt~@8q56a5*`!=rH0qKD{Q5|rk z_ZXoP26#W7ba=-4sjEMkjk-HO`D~OVVa0~oMEbnw^<*1RQ%LBuA20moSFzONB&a}w zVHlx39feXuvC(T^J6h1Woa zm|&vcE;HLbH@Uz4Z=kurgBU*d$Hlf4p^`(u+hQkt&tF)(R6o<}+tM>@fAm-Sf5!p; z`DjwMV9x=iIpgsEd#IhZ&fin#OodrN(6m|S_MFd3e3DT(rP86{kG_|0rB#&byT5-j zK{yb~KiJ00=46uOTyx!rD3g*Jx6Td>8F2G+o0;uYAEl1T7tfK*7uHG;5lPUX+d6-I zE1z-PF!fY0TSH;%b@~87B2C!Y@Qk+~Ls||w`2MZ2#D7I{=A3&UQ&s2m<_lGlSG$^o z6inYUm7F~KrU)X-vm@JlTc|(s^V-t0*U`+O#t|<7d{ZW{|5QGXLZNp>ebhJ6%wR5N zOeBtc_h=&WD{gn|Ck-0>^3}nt;DO8Hw^vqt{on;*@!Gy^+EdS`@85-eyxs4EHrErE zW>4jSPkzs8np^t~XglEA(wyLh%g;Q1HZLIgNtG7h{hEc}Jo-#q^65w6zzzGA5AdKi zgs1$e(?|*dgijR6OITwVyz9faru)4r-~4DAn_T%Ic(PZ}o60rOO&={PU2!sHd%s_2 z58a~pLxhQJZgiKB)kj9QX>5A_^wZCG-W~Yoed)`SDNhp@t~yhG`f1_Q)j{R+R2iy9-PZ zpbp`zaqa1Wf7-kKdwFCRpBAJm-Q7Z6bmxn9aye< zYV`rFXB%(dO~hps3T1&+EefBM9&tQ*#&+BBsTW=mfC_q&Gw67}dVKj0#opz~duA%b zam9(v>hEnuWR=T#H9#G5Yrk=}o8`HntNQDEZaDq8z+>UJim<+;AjBt8H4`QYa?%ku z=$2&FwxQ{rvR@vBYxEl}86Ll!%?&gA5 zRIrC<7p>{})4uJQvdg7!DpM*xFFg0_R>;zLw$r`nNLUY$;=2cjhe|RQjI~A1(YeRl z*1Z4H$}N6--n+67%QAPJT-hcyx9~~v=^vKgRI8G(E4)a#=IIw<5JVIw$s+=GyjEg* z+m{Px2KL*w=)F_IQvL1LSyR?aQ+X=#MdYGUP*}~o`SO%j|NdI@?4NTV*5sYL-$waf zj=_EZQnIWG>7r_c4i#IC1BzO@;4U}Ako=k8EUtZ3o=%ZoMRw>};S^C|@wWqLpAk?mwe1YVJhJI-vaRQOWPAG)Jm0 ztx%I1juyDgFLeHSLj&;p5G!K}9nQjL#e!YMhf0T9NS_;SRaaeY?B_Qo@h^Y_7$F~7 z)GD3?kO8?}3CqMM@v1Rhsu_te1CV)`Q!vBi@+*{W58admoI;(aIb<$k9x5M2`i+~< zaPzfW$xI#*s?Eh$Dsfk<^r*9y73Jc}BJ+KO1u3Ppf`t!#8%2MMoZkT6sQt1jwO*YXp3y<(7pQp5sJ5O`b1n$SI$>Ly`L2$^%} zGPuyBUb-iQ=RFLRW}`+23E1ACRlEy-Bc`8 z{Ww7WleVK!V16=F4Y)&xRG8^N%igcZUI#KYUR)a7=6nRwEqcw` zq+}XZN9IWvbp$gLVO>OY$eM{FafbFTU^aqD>;uW7Qz;~Hcl}0D&{&Nm$z@2JE#xf% zlu&QrC3b_%ijKAa|4xp0*B90lg=P%=RG_8KSNeR$k}`g9vxnl4Q`&X~NK+&u2u<8S zJewl)aJGgS`UW}uk`*P@-J;*J1d?L$O3ANk`5LO-(gS&0)MBHfdY4ELK@^+AqFY2i zd4Bk6o8G~S&`lBy6I+PQVpv}SI^8(R89|u_!S?M~NG-%bqKTknN`zmevb)NKnWwyI zq2B6)sQH^Z^LjJWS1x-<~$rE4;KrM zvfo>YSiH54-2UvVvdP{Xzib@zbFgG^Bq|}SKg-1wR*WpQ8!Uac$G1zcs7UEl#I_yr z7tG9YM3{J&Z9P?<)ZVA@TIJJTu1*?P`~8}VvN>kMhdaN2a#}1pg9?)X#(}p}!X+Uy zYnB8BY^SJoEV?M4#JhdEIv=k{AHW>Z4TvF2sa~50<5g>5Z6I|3*wQZa+d~wqLO0`a zXEF<(AMg6E2C9UILgC*LA7Dd1`0u=A4hj{EqAhCr-BYz`kE@dY%7^8pT54iay9uNi z2YQi->K7FX^Zsgpr`-hMAp=w9{I`En=Zn;L^P{{R1il34NC zP6Ac6VF1oHst+?ge2D4{!l%8r)gR^k=XTYVuKH+4GnLJ(`fr8(y8lb)!XV__pD zZTV~<9W{0us?N)s^PMiLzKeJJuZSrqp>yj8J@O-CT7`|lVC6rh$Ei(>LgC|p_#yw@ zyKbw>A6I@Ax_7kxS=)7Xs^6RVpWpkPc58VqW9uPY*nyY|G1|mS@=NIyGoA}i==!15 zHLtgUVaN7s&$qFyX_mfr+pZ0317oi4{nuFIu(wYqpUw3f)my6(=+I;Hm1dI~gk9g< zV$y=XEz)ZH^>CQy^Lle_Gtvkyn}z8x5Fw8{Jr z?jJI1m<|n9@$|L6Kl^s>pm*-yz3frIykAu2qqL1(=9Rx6(WJ@3)6qB*{X zbYjW-^?vzpBSrRVP*X!zA*UWPwA*-VAKz+L@oT{40}Q79xVuNg zTwai~T>S#vYY|cDot_Hk+=Cn21lBit;JCg#E-r2f8Mh|>0>$Un)l}NW&~`0dj#-~8 zfBHd$iW%=8FTPlR>9xN$YVH;FUd#veZ<$j4GOLOH)cqaj0WjBm{HN{e+0J5N(;r#Y zl~dwfz4hYsY7bYu+_tMDvL?D=cxqUR5mY}EGI2mx!-~#*E<*CiOwt6;)kVr zExwNWYwm}$-z-UE|E5F&RWJQ$e3L06_~n(*y5sEaPgqWyR{rR|U&n^PHItBd7$x%A zH}fhhzO4=Ui_Z+z9=MRtHVw{#>iI%|@w%BJo&av`WY^1DWe+pg?A~VdNV_n2`P5}k z-S3CZ?A9BMPR*CsO(sDGb@1)mzUdS<>tzq7Zw#9$hxK?&f~{_VPXqb0!hMRJo!!FI z1-mCNK3~g&2VR1Zrm)MPvQePW32w&%Qr;w;S%REm4qR~a9*(9P8nkAw9%;4~wR}u1 zRCjE8pn}n-m)tr)wg?*`Wj4N_A6ubn2J8qm9W<0^-YOQB%0D$MhlZQ$OE+ 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

= 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 T$@E$sV&w6dEZFD$Rq2TQr&y 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%0Dl-~jH|Lc~r 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 S(pmXt^Wm1J2}A!{`Tqg+tf!&? literal 146121 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 boqhLDc=p?p*ibw9S*y=%K0PvP`FH;d3cF>$ diff --git a/doc/user/installation_using_cmake.md b/doc/user/installation_using_cmake.md index 8789ba00..9e90bfbd 100644 --- a/doc/user/installation_using_cmake.md +++ b/doc/user/installation_using_cmake.md @@ -4,7 +4,6 @@ ## BuildCC User options - BUILDCC_INSTALL: ON -- BUILDCC_FLATBUFFERS_FLATC: ON - BUILDCC_BUILD_AS_SINGLE_LIB: ON - Generates `libbuildcc` - BUILDCC_BUILD_AS_INTERFACE_LIB: OFF diff --git a/docs/source/arch/project_layout.rst b/docs/source/arch/project_layout.rst index 8fe5298e..a62579f6 100644 --- a/docs/source/arch/project_layout.rst +++ b/docs/source/arch/project_layout.rst @@ -38,7 +38,7 @@ Project Layout * third_party ** CLI11 ** cpputest - ** flatbuffers + ** json ** fmt ** spdlog ** taskflow @@ -109,7 +109,7 @@ Global cmake variables and custom_targets * build_flags.cmake * test_flags.cmake * target - * flatbuffers.cmake + * json.cmake * fmt.cmake * spdlog.cmake * tpl.cmake @@ -144,7 +144,7 @@ example third_party ----------- -* Flatbuffers +* JSON * Fmtlib * Spdlog * CLI11 diff --git a/docs/source/arch/software_heirarchy.rst b/docs/source/arch/software_heirarchy.rst index 20877103..feb4540e 100644 --- a/docs/source/arch/software_heirarchy.rst +++ b/docs/source/arch/software_heirarchy.rst @@ -11,7 +11,7 @@ BuildCC single lib .. uml:: - rectangle Flatbuffers as flatbuffers + rectangle JSON as json rectangle fmt as fmt rectangle spdlog as spdlog rectangle Taskflow as taskflow @@ -20,7 +20,7 @@ BuildCC single lib rectangle BuildCC as buildcc - flatbuffers -up-> buildcc + json -up-> buildcc fmt -up-> buildcc spdlog -up-> buildcc taskflow -up-> buildcc @@ -39,7 +39,7 @@ BuildCC interface lib .. uml:: - rectangle Flatbuffers as flatbuffers #palegreen + rectangle JSON as json #palegreen rectangle fmt as fmt #palegreen rectangle spdlog as spdlog #palegreen rectangle Taskflow as taskflow #palegreen @@ -65,7 +65,7 @@ BuildCC interface lib cli11 -up-> args taskflow -up-> register - flatbuffers .up.> schema + json .up.> schema env -up-> schema schema -up-> toolchain diff --git a/docs/source/arch/testing.rst b/docs/source/arch/testing.rst index 58c0b5ef..31423bef 100644 --- a/docs/source/arch/testing.rst +++ b/docs/source/arch/testing.rst @@ -37,17 +37,13 @@ mock_toolchain mock_target ^^^^^^^^^^^^ -.. doxygenfunction:: GeneratorRunner +.. doxygenfunction:: CustomGeneratorRunner -.. doxygenfunction:: GeneratorExpect_InputRemoved +.. doxygenfunction:: CustomGeneratorExpect_IdRemoved -.. doxygenfunction:: GeneratorExpect_InputAdded +.. doxygenfunction:: CustomGeneratorExpect_IdAdded -.. doxygenfunction:: GeneratorExpect_InputUpdated - -.. doxygenfunction:: GeneratorExpect_OutputChanged - -.. doxygenfunction:: GeneratorExpect_CommandChanged +.. doxygenfunction:: CustomGeneratorExpect_IdUpdated From the :doc:`serialization_schema` **generator** we can see that our generator has 3 rebuild conditions diff --git a/docs/source/examples/gcc.rst b/docs/source/examples/gcc.rst index c67e3289..fb19a1a4 100644 --- a/docs/source/examples/gcc.rst +++ b/docs/source/examples/gcc.rst @@ -218,7 +218,7 @@ Use BuildCC with CMake # fmt is imported by spdlog by default find_package(fmt_package NAMES "fmt" REQUIRED) find_package(spdlog_package NAMES "spdlog" REQUIRED) - find_package(flatbuffers_package NAMES "flatbuffers" REQUIRED) + find_package(nlohmann_json_package NAMES "nlohmann_json" REQUIRED) find_package(taskflow_package NAMES "Taskflow" "taskflow" REQUIRED) find_package(CLI11_package NAMES "CLI11" REQUIRED) find_package(tiny_process_library_package NAMES "tiny-process-library" REQUIRED) @@ -227,7 +227,7 @@ Use BuildCC with CMake message("Find package: ${fmt_package_DIR}") message("Find package: ${spdlog_package_DIR}") - message("Find package: ${flatbuffers_package_DIR}") + message("Find package: ${nlohmann_json_package_DIR}") message("Find package: ${taskflow_package_DIR}") message("Find package: ${CLI11_package_DIR}") message("Find package: ${tiny_process_library_package_DIR}") # diff --git a/docs/source/getting_started/buildexe_setup.rst b/docs/source/getting_started/buildexe_setup.rst index 8d2b5918..7c554971 100644 --- a/docs/source/getting_started/buildexe_setup.rst +++ b/docs/source/getting_started/buildexe_setup.rst @@ -144,7 +144,7 @@ For example we download the **fmt library** to our libs folder **** [git cloned] *** spdlog **** [git cloned] - *** flatbuffers + *** json **** [git cloned] ** host *** gcc_x86_64-linux-gnu_9.3.0.toml diff --git a/docs/source/intro/toc.rst b/docs/source/intro/toc.rst index 3e2b01f5..46b05085 100644 --- a/docs/source/intro/toc.rst +++ b/docs/source/intro/toc.rst @@ -25,7 +25,7 @@ Pre-requisites * C++17 filesystem library support * C++11 thread library support * Third Party Libraries (See License below) - * Flatbuffers v2.0.0 + * JSON v3.11.2 * Taskflow v3.1.0 * CLI11 v2.1.0 * Tiny Process Library v2.0.4 @@ -68,6 +68,6 @@ Licenses * `Tiny Process Library `_ (Process handling) [MIT License] * `Taskflow `_ (Parallel Programming) [MIT License] [Header Only] * See also `3rd-Party `_ used by Taskflow -* `Flatbuffers `_ (Serialization) [Apache-2.0 License] [Header Only] +* `Nlohmann::Json `_ (Serialization) [MIT License] [Header Only] * `CLI11 `_ (Argument Parsing) [BSD-3-Clause License] [Header Only] * `CppUTest `_ (Unit Testing/Mocking) [BSD-3-Clause License] diff --git a/docs/source/user_api/generator.rst b/docs/source/user_api/generator.rst index 9301e6a3..364a1cf0 100644 --- a/docs/source/user_api/generator.rst +++ b/docs/source/user_api/generator.rst @@ -1,16 +1,26 @@ -Generator -========= +Template Generator +=================== -generator.h ------------ +> TODO, -.. doxygenclass:: buildcc::Generator +File Generator +=============== -.. doxygentypedef:: BaseGenerator +> TODO + +Custom Generator +================ + +custom_generator.h +------------------- + +.. doxygenclass:: buildcc::CustomGenerator Example -------- +> TODO, Update example + .. code-block:: cpp :linenos: diff --git a/docs/source/user_api/target.rst b/docs/source/user_api/target.rst index 5d3d7aa7..5d7fa001 100644 --- a/docs/source/user_api/target.rst +++ b/docs/source/user_api/target.rst @@ -36,11 +36,6 @@ sync_api.h .. doxygenclass:: buildcc::internal::SyncApi -target_getter.h ------------------ - -.. doxygenclass:: buildcc::internal::TargetInfoGetter - TargetInfo =========== diff --git a/docs/source/user_api/toolchain_utils.rst b/docs/source/user_api/toolchain_utils.rst index 6a05645f..b3161529 100644 --- a/docs/source/user_api/toolchain_utils.rst +++ b/docs/source/user_api/toolchain_utils.rst @@ -8,11 +8,6 @@ file_ext.h .. doxygenenum:: buildcc::FileExt -function_lock.h ------------------ - -.. doxygenclass:: buildcc::FunctionLock - toolchain_config.h -------------------- diff --git a/example/gcc/AfterInstall/CMakeLists.txt b/example/gcc/AfterInstall/CMakeLists.txt index 04a8cd7a..55b3aca4 100644 --- a/example/gcc/AfterInstall/CMakeLists.txt +++ b/example/gcc/AfterInstall/CMakeLists.txt @@ -12,7 +12,6 @@ project(simple) # fmt is imported by spdlog by default find_package(fmt_package NAMES "fmt" REQUIRED) find_package(spdlog_package NAMES "spdlog" REQUIRED) -find_package(flatbuffers_package NAMES "Flatbuffers" "flatbuffers" REQUIRED) find_package(nlohmann_json_package NAMES "nlohmann_json" REQUIRED) find_package(taskflow_package NAMES "Taskflow" "taskflow" REQUIRED) find_package(tl_optional_package NAMES "tl-optional" REQUIRED) @@ -23,7 +22,6 @@ find_package(buildcc_package NAMES "buildcc" REQUIRED) message("Find package: ${fmt_package_DIR}") message("Find package: ${spdlog_package_DIR}") -message("Find package: ${flatbuffers_package_DIR}") message("Find package: ${nlohmann_json_package_DIR}") message("Find package: ${tl_optional_package_DIR}") message("Find package: ${taskflow_package_DIR}") diff --git a/third_party/flatbuffers b/third_party/flatbuffers deleted file mode 160000 index a9a295fe..00000000 --- a/third_party/flatbuffers +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a9a295fecf3fbd5a4f571f53b01f63202a3e2113 From 59f43d58cb9f5b46ea5e53375b4edd414a679e5f Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Nov 2022 09:11:05 -0800 Subject: [PATCH 32/35] [Functionality] Reduce Custom generator scope to a Single stage generator (#227) --- .../lib/target/cmake/common_target_src.cmake | 3 + .../target/include/target/custom_generator.h | 240 +++--- .../custom_generator/custom_blob_handler.h | 59 ++ .../custom_generator_context.h | 45 ++ .../target/include/target/file_generator.h | 2 - .../include/target/template_generator.h | 2 - .../src/custom_generator/custom_generator.cpp | 193 +---- .../test/target/test_custom_generator.cpp | 706 ++---------------- .../include/schema/custom_generator_schema.h | 7 - cmake/coverage/gcovr.cmake | 1 + cmake/tool/cppcheck.cmake | 2 +- 11 files changed, 337 insertions(+), 923 deletions(-) create mode 100644 buildcc/lib/target/include/target/custom_generator/custom_blob_handler.h create mode 100644 buildcc/lib/target/include/target/custom_generator/custom_generator_context.h diff --git a/buildcc/lib/target/cmake/common_target_src.cmake b/buildcc/lib/target/cmake/common_target_src.cmake index 5a10bfe8..92822197 100644 --- a/buildcc/lib/target/cmake/common_target_src.cmake +++ b/buildcc/lib/target/cmake/common_target_src.cmake @@ -27,6 +27,9 @@ set(COMMON_TARGET_SRCS include/target/api/target_getter.h # Generator + include/target/custom_generator/custom_generator_context.h + include/target/custom_generator/custom_blob_handler.h + src/custom_generator/custom_generator.cpp include/target/custom_generator.h src/generator/file_generator.cpp diff --git a/buildcc/lib/target/include/target/custom_generator.h b/buildcc/lib/target/include/target/custom_generator.h index e0263419..0712cde5 100644 --- a/buildcc/lib/target/include/target/custom_generator.h +++ b/buildcc/lib/target/include/target/custom_generator.h @@ -30,69 +30,28 @@ #include "schema/custom_generator_serialization.h" #include "schema/path.h" +#include "custom_generator/custom_blob_handler.h" +#include "custom_generator/custom_generator_context.h" + #include "target/common/target_env.h" namespace buildcc { -// TODO, Shift to a different file -// TODO, Check if we need the "id" here as well -class CustomGeneratorContext { -public: - CustomGeneratorContext(const env::Command &c, const fs_unordered_set &i, - const fs_unordered_set &o, - const std::vector &ub) - : command(c), inputs(i), outputs(o), userblob(ub) {} - - const env::Command &command; - const fs_unordered_set &inputs; - const fs_unordered_set &outputs; - const std::vector &userblob; -}; - -// clang-format off -using GenerateCb = std::function; - -using DependencyCb = std::function &&)>; -// clang-format on - -class CustomBlobHandler { -public: - CustomBlobHandler() = default; - virtual ~CustomBlobHandler() = default; - - bool CheckChanged(const std::vector &previous, - const std::vector ¤t) const { - env::assert_fatal( - Verify(previous), - "Stored blob is corrupted or User verification is incorrect"); - env::assert_fatal( - Verify(current), - "Current blob is corrupted or User verification is incorrect"); - return !IsEqual(previous, current); +struct UserCustomGeneratorSchema : public internal::CustomGeneratorSchema { + struct UserIdInfo : internal::CustomGeneratorSchema::IdInfo { + fs_unordered_set inputs; // TODO, Remove + GenerateCb generate_cb; + std::shared_ptr blob_handler{nullptr}; + + void ConvertToInternal() { + internal_inputs = internal::path_schema_convert( + inputs, internal::Path::CreateExistingPath); + userblob = blob_handler != nullptr ? blob_handler->GetSerializedData() + : std::vector(); + } }; - std::vector GetSerializedData() const { - auto serialized_data = Serialize(); - env::assert_fatal( - Verify(serialized_data), - "Serialized data is corrupted or Serialize function is incorrect"); - return serialized_data; - } - -private: - virtual bool Verify(const std::vector &serialized_data) const = 0; - virtual bool IsEqual(const std::vector &previous, - const std::vector ¤t) const = 0; - virtual std::vector Serialize() const = 0; -}; - -struct UserIdInfo : internal::CustomGeneratorSchema::IdInfo { - fs_unordered_set inputs; - GenerateCb generate_cb; - std::shared_ptr blob_handler{nullptr}; -}; - -struct UserCustomGeneratorSchema : public internal::CustomGeneratorSchema { + using UserIdPair = std::pair; std::unordered_map ids; void ConvertToInternal() { @@ -110,7 +69,8 @@ class CustomGenerator : public internal::BuilderInterface { CustomGenerator(const std::string &name, const TargetEnv &env) : name_(name), env_(env.GetTargetRootDir(), env.GetTargetBuildDir() / name), - serialization_(env_.GetTargetBuildDir() / fmt::format("{}.bin", name)) { + serialization_(env_.GetTargetBuildDir() / fmt::format("{}.json", name)), + comparator_(serialization_.GetLoad(), user_) { Initialize(); } virtual ~CustomGenerator() = default; @@ -137,33 +97,12 @@ class CustomGenerator : public internal::BuilderInterface { * @param generate_cb User-defined generate callback to build outputs from the * provided inputs */ - void AddIdInfo(const std::string &id, - const std::unordered_set &inputs, - const std::unordered_set &outputs, - const GenerateCb &generate_cb, - std::shared_ptr blob_handler = nullptr); - - // TODO, Doc - void AddGroupInfo(const std::string &group_id, - std::initializer_list ids, - const DependencyCb &dependency_cb = DependencyCb()); - - // Callbacks - /** - * @brief Setup dependencies between Tasks using their `id` - * For example: `task_map["id1"].precede(task_map["id2"])` - * - * IMPORTANT: Successor tasks will not automatically run if dependent task is - * run. - * The Dependency callback only sets precedence (order in which your tasks - * should run) - * Default behaviour when dependency callback is not supplied: All task `id`s - * run in parallel. - * - * @param dependency_cb Unordered map of `id` and `task` - * The map can be safely mutated. - */ - void AddDependencyCb(const DependencyCb &dependency_cb); + void + AddIdInfo(const std::string &id, + const std::unordered_set &inputs, + const std::unordered_set &outputs, + const GenerateCb &generate_cb, + const std::shared_ptr &blob_handler = nullptr); void Build() override; @@ -176,19 +115,100 @@ class CustomGenerator : public internal::BuilderInterface { const fs::path &GetBuildDir() const { return env_.GetTargetBuildDir(); } const std::string &Get(const std::string &file_identifier) const; +private: + struct Comparator { + Comparator(const internal::CustomGeneratorSchema &loaded, + const UserCustomGeneratorSchema &us) + : loaded_schema_(loaded), current_schema_(us) {} + + enum class State { + kRemoved, + kAdded, + kCheckLater, + }; + + void AddAllIds() { + const auto &curr_ids = current_schema_.ids; + for (const auto &[id, _] : curr_ids) { + id_state_info_.at(State::kAdded).insert(id); + } + } + + void CompareIds() { + const auto &prev_ids = loaded_schema_.internal_ids; + const auto &curr_ids = current_schema_.ids; + + for (const auto &[prev_id, _] : prev_ids) { + if (curr_ids.find(prev_id) == curr_ids.end()) { + // Id Removed condition, previous id is not present in the current run + id_state_info_.at(State::kRemoved).insert(prev_id); + } + } + + for (const auto &[curr_id, _] : curr_ids) { + if (prev_ids.find(curr_id) == prev_ids.end()) { + // Id Added condition + id_state_info_.at(State::kAdded).insert(curr_id); + } else { + // Id Check Later condition + id_state_info_.at(State::kCheckLater).insert(curr_id); + } + } + } + + bool IsChanged(const std::string &id) const { + const auto &previous_id_info = loaded_schema_.internal_ids.at(id); + const auto ¤t_id_info = current_schema_.ids.at(id); + + bool changed = internal::CheckPaths(previous_id_info.internal_inputs, + current_id_info.internal_inputs) != + internal::PathState::kNoChange; + changed = changed || internal::CheckChanged(previous_id_info.outputs, + current_id_info.outputs); + if (!changed && current_id_info.blob_handler != nullptr) { + // We only check blob handler if not changed by inputs/outputs + // Checking blob_handler could be expensive so this optimization is made + // to run only when changed == false + changed = current_id_info.blob_handler->CheckChanged( + previous_id_info.userblob, current_id_info.userblob); + } + return changed; + } + + const std::unordered_set &GetRemovedIds() const { + return id_state_info_.at(State::kRemoved); + } + + const std::unordered_set &GetAddedIds() const { + return id_state_info_.at(State::kAdded); + } + + const std::unordered_set &GetCheckLaterIds() const { + return id_state_info_.at(State::kCheckLater); + } + + bool IsIdAdded(const std::string &id) const { + return id_state_info_.at(State::kAdded).count(id) == 1; + } + + private: + const internal::CustomGeneratorSchema &loaded_schema_; + const UserCustomGeneratorSchema ¤t_schema_; + std::unordered_map> id_state_info_{ + {State::kRemoved, std::unordered_set()}, + {State::kAdded, std::unordered_set()}, + {State::kCheckLater, std::unordered_set()}, + }; + }; + private: void Initialize(); - void TaskRunner(bool run, const std::string &id); - tf::Task CreateTaskRunner(tf::Subflow &subflow, bool build, - const std::string &id); + tf::Task CreateTaskRunner(tf::Subflow &subflow, const std::string &id); + void TaskRunner(const std::string &id); void GenerateTask(); - void BuildGenerate(std::unordered_set &gen_selected_ids, - std::unordered_set &dummy_gen_selected_ids); - - void InvokeDependencyCb(std::unordered_map - &®istered_tasks) const noexcept; + void BuildGenerate(); // Recheck states void IdRemoved(); @@ -199,29 +219,6 @@ class CustomGenerator : public internal::BuilderInterface { const env::Command &ConstCommand() const { return command_; } env::Command &RefCommand() { return command_; } -private: - struct GroupMetadata { - std::vector ids; - DependencyCb dependency_cb; - - void InvokeDependencyCb(const std::string &group_id, - std::unordered_map - &®istered_tasks) const noexcept { - if (!dependency_cb) { - return; - } - try { - dependency_cb(std::move(registered_tasks)); - } catch (...) { - env::log_critical( - __FUNCTION__, - fmt::format("Dependency callback failed for group id {}", - group_id)); - env::set_task_state(env::TaskState::FAILURE); - } - } - }; - private: std::string name_; TargetEnv env_; @@ -229,17 +226,16 @@ class CustomGenerator : public internal::BuilderInterface { // Serialization UserCustomGeneratorSchema user_; - std::unordered_map grouped_ids_; - std::unordered_set ungrouped_ids_; + + // Comparator + Comparator comparator_; std::mutex success_schema_mutex_; - std::unordered_map success_schema_; + std::unordered_map + success_schema_; // Internal env::Command command_; - - // Callbacks - DependencyCb dependency_cb_; }; } // namespace buildcc diff --git a/buildcc/lib/target/include/target/custom_generator/custom_blob_handler.h b/buildcc/lib/target/include/target/custom_generator/custom_blob_handler.h new file mode 100644 index 00000000..1c268301 --- /dev/null +++ b/buildcc/lib/target/include/target/custom_generator/custom_blob_handler.h @@ -0,0 +1,59 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TARGET_CUSTOM_GENERATOR_CUSTOM_BLOB_HANDLER_H_ +#define TARGET_CUSTOM_GENERATOR_CUSTOM_BLOB_HANDLER_H_ + +#include + +#include "env/assert_fatal.h" + +namespace buildcc { + +class CustomBlobHandler { +public: + CustomBlobHandler() = default; + virtual ~CustomBlobHandler() = default; + + bool CheckChanged(const std::vector &previous, + const std::vector ¤t) const { + env::assert_fatal( + Verify(previous), + "Stored blob is corrupted or User verification is incorrect"); + env::assert_fatal( + Verify(current), + "Current blob is corrupted or User verification is incorrect"); + return !IsEqual(previous, current); + }; + + std::vector GetSerializedData() const { + auto serialized_data = Serialize(); + env::assert_fatal( + Verify(serialized_data), + "Serialized data is corrupted or Serialize function is incorrect"); + return serialized_data; + } + +private: + virtual bool Verify(const std::vector &serialized_data) const = 0; + virtual bool IsEqual(const std::vector &previous, + const std::vector ¤t) const = 0; + virtual std::vector Serialize() const = 0; +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h b/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h new file mode 100644 index 00000000..207015d9 --- /dev/null +++ b/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h @@ -0,0 +1,45 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TARGET_CUSTOM_GENERATOR_CUSTOM_GENERATOR_CONTEXT_H_ +#define TARGET_CUSTOM_GENERATOR_CUSTOM_GENERATOR_CONTEXT_H_ + +#include "schema/path.h" + +#include "env/command.h" + +namespace buildcc { + +class CustomGeneratorContext { +public: + CustomGeneratorContext(const env::Command &c, const fs_unordered_set &i, + const fs_unordered_set &o, + const std::vector &ub) + : command(c), inputs(i), outputs(o), userblob(ub) {} + + const env::Command &command; + const fs_unordered_set &inputs; + const fs_unordered_set &outputs; + const std::vector &userblob; +}; + +// clang-format off +using GenerateCb = std::function; +// clang-format on + +} // namespace buildcc + +#endif diff --git a/buildcc/lib/target/include/target/file_generator.h b/buildcc/lib/target/include/target/file_generator.h index e11b2b21..9897b5fc 100644 --- a/buildcc/lib/target/include/target/file_generator.h +++ b/buildcc/lib/target/include/target/file_generator.h @@ -68,8 +68,6 @@ class FileGenerator : public CustomGenerator { // Restrict access to certain custom generator APIs private: - using CustomGenerator::AddDependencyCb; - using CustomGenerator::AddGroupInfo; using CustomGenerator::AddIdInfo; using CustomGenerator::Build; diff --git a/buildcc/lib/target/include/target/template_generator.h b/buildcc/lib/target/include/target/template_generator.h index 79706a4c..73c892e7 100644 --- a/buildcc/lib/target/include/target/template_generator.h +++ b/buildcc/lib/target/include/target/template_generator.h @@ -42,8 +42,6 @@ class TemplateGenerator : public CustomGenerator { // Restrict access to certain custom generator APIs private: - using CustomGenerator::AddDependencyCb; - using CustomGenerator::AddGroupInfo; using CustomGenerator::AddIdInfo; using CustomGenerator::Build; diff --git a/buildcc/lib/target/src/custom_generator/custom_generator.cpp b/buildcc/lib/target/src/custom_generator/custom_generator.cpp index c7cb8725..b60283e8 100644 --- a/buildcc/lib/target/src/custom_generator/custom_generator.cpp +++ b/buildcc/lib/target/src/custom_generator/custom_generator.cpp @@ -55,12 +55,12 @@ void CustomGenerator::AddIdInfo( const std::string &id, const std::unordered_set &inputs, const std::unordered_set &outputs, const GenerateCb &generate_cb, - std::shared_ptr blob_handler) { + const std::shared_ptr &blob_handler) { env::assert_fatal(user_.ids.find(id) == user_.ids.end(), fmt::format("Duplicate id {} detected", id)); ASSERT_FATAL(generate_cb, "Invalid callback provided"); - UserIdInfo schema; + UserCustomGeneratorSchema::UserIdInfo schema; for (const auto &i : inputs) { fs::path input = string_as_path(command_.Construct(i)); schema.inputs.emplace(std::move(input)); @@ -70,34 +70,8 @@ void CustomGenerator::AddIdInfo( schema.outputs.emplace(std::move(output)); } schema.generate_cb = generate_cb; - schema.blob_handler = std::move(blob_handler); + schema.blob_handler = blob_handler; user_.ids.try_emplace(id, std::move(schema)); - ungrouped_ids_.emplace(id); -} - -void CustomGenerator::AddGroupInfo(const std::string &group_id, - std::initializer_list ids, - const DependencyCb &dependency_cb) { - // Verify that the ids exist - // Remove those ids from ungrouped_ids - for (const auto &id : ids) { - env::assert_fatal(user_.ids.find(id) != user_.ids.end(), - fmt::format("Id '{}' is not found", id)); - ungrouped_ids_.erase(id); - } - - env::assert_fatal(grouped_ids_.find(group_id) == grouped_ids_.end(), - fmt::format("Group Id '{}' duplicate found", group_id)); - - // Group map is used to group similar ids in a single subflow - GroupMetadata group_metadata; - group_metadata.ids = ids; - group_metadata.dependency_cb = dependency_cb; - grouped_ids_.try_emplace(group_id, std::move(group_metadata)); -} - -void CustomGenerator::AddDependencyCb(const DependencyCb &dependency_cb) { - dependency_cb_ = dependency_cb; } void CustomGenerator::Build() { @@ -127,48 +101,25 @@ void CustomGenerator::Initialize() { tf_.name(name_); } -void CustomGenerator::BuildGenerate( - std::unordered_set &gen_selected_ids, - std::unordered_set &dummy_gen_selected_ids) { +void CustomGenerator::BuildGenerate() { if (!serialization_.IsLoaded()) { - std::for_each(user_.ids.begin(), user_.ids.end(), [&](const auto &iter) { - gen_selected_ids.insert(iter.first); - }); + comparator_.AddAllIds(); dirty_ = true; } else { - // DONE, Conditionally select internal_ids depending on what has - // changed - const auto &prev_ids = serialization_.GetLoad().internal_ids; - const auto &curr_ids = user_.ids; - - // DONE, MAP REMOVED condition Check if prev_ids exists in - // curr_ids If prev_ids does not exist in - // curr_ids, has been removed from existing build We need this - // condition to only set the dirty_ flag - for (const auto &[id, _] : prev_ids) { - if (curr_ids.find(id) == curr_ids.end()) { - // MAP REMOVED condition - IdRemoved(); - dirty_ = true; - break; - } + // For IDS + comparator_.CompareIds(); + + const bool is_removed = !comparator_.GetRemovedIds().empty(); + const bool is_added = !comparator_.GetAddedIds().empty(); + dirty_ = is_removed || is_added; + + if (is_removed) { + IdRemoved(); } - // DONE, MAP ADDED condition Check if curr_ids exists in - // prev_ids If curr_ids does not exist in - // prev_ids, has been added to existing build - for (const auto &[id, _] : curr_ids) { - if (prev_ids.find(id) == prev_ids.end()) { - // MAP ADDED condition - IdAdded(); - gen_selected_ids.insert(id); - dirty_ = true; - } else { - // MAP UPDATED condition (*checked later) - // This is because tasks can have dependencies amongst each other we can - // compute task level rebuilds later - dummy_gen_selected_ids.insert(id); - } + for (const auto &id : comparator_.GetAddedIds()) { + (void)id; + IdAdded(); } } } @@ -180,56 +131,24 @@ void CustomGenerator::GenerateTask() { } try { - std::unordered_map registered_tasks; - // Selected ids for build - std::unordered_set selected_ids; - std::unordered_set dummy_selected_ids; - BuildGenerate(selected_ids, dummy_selected_ids); - - // Grouped tasks - for (const auto &[first, second] : grouped_ids_) { - const auto &group_id = first; - const auto &group_metadata = second; - auto group_task = subflow.emplace([&](tf::Subflow &s) { - std::unordered_map reg_tasks; - - if (env::get_task_state() != env::TaskState::SUCCESS) { - return; - } - - for (const auto &id : group_metadata.ids) { - bool build = selected_ids.count(id) == 1; - auto task = CreateTaskRunner(s, build, id); - task.name(id); - reg_tasks.try_emplace(id, task); - } - - // Dependency callback - group_metadata.InvokeDependencyCb(group_id, std::move(reg_tasks)); - - // NOTE, Do not call detach otherwise this will fail - s.join(); - }); - group_task.name(group_id); - registered_tasks.try_emplace(group_id, group_task); - } + BuildGenerate(); - // Ungrouped tasks - for (const auto &id : ungrouped_ids_) { - bool build = selected_ids.count(id) == 1; - auto task = CreateTaskRunner(subflow, build, id); + // Create runner for each added/updated id + for (const auto &id : comparator_.GetAddedIds()) { + auto task = CreateTaskRunner(subflow, id); task.name(id); - registered_tasks.try_emplace(id, task); } - // Dependencies between tasks - InvokeDependencyCb(std::move(registered_tasks)); + for (const auto &id : comparator_.GetCheckLaterIds()) { + auto task = CreateTaskRunner(subflow, id); + task.name(id); + } // NOTE, Do not call detach otherwise this will fail subflow.join(); - // Store dummy_selected and successfully run schema + // Store if (dirty_) { UserCustomGeneratorSchema user_final_schema; user_final_schema.ids.insert(success_schema_.begin(), @@ -240,7 +159,6 @@ void CustomGenerator::GenerateTask() { env::assert_fatal(serialization_.StoreToFile(), fmt::format("Store failed for {}", name_)); } - } catch (...) { env::set_task_state(env::TaskState::FAILURE); } @@ -249,67 +167,34 @@ void CustomGenerator::GenerateTask() { generate_task.name(kGenerateTaskName); } -void CustomGenerator::InvokeDependencyCb( - std::unordered_map &®istered_tasks) - const noexcept { - if (dependency_cb_) { - try { - dependency_cb_(std::move(registered_tasks)); - } catch (...) { - env::log_critical(__FUNCTION__, "Dependency callback failed"); - env::set_task_state(env::TaskState::FAILURE); - } - } -} - -tf::Task CustomGenerator::CreateTaskRunner(tf::Subflow &subflow, bool build, +tf::Task CustomGenerator::CreateTaskRunner(tf::Subflow &subflow, const std::string &id) { - return subflow.emplace([&, build, id]() { + return subflow.emplace([&, id]() { if (env::get_task_state() != env::TaskState::SUCCESS) { return; } try { - TaskRunner(build, id); + TaskRunner(id); } catch (...) { env::set_task_state(env::TaskState::FAILURE); } }); } -void CustomGenerator::TaskRunner(bool run, const std::string &id) { - // Convert - { - auto &curr_id_info = user_.ids.at(id); - curr_id_info.internal_inputs = internal::path_schema_convert( - curr_id_info.inputs, internal::Path::CreateExistingPath); - curr_id_info.userblob = curr_id_info.blob_handler != nullptr - ? curr_id_info.blob_handler->GetSerializedData() - : std::vector(); - } +void CustomGenerator::TaskRunner(const std::string &id) { + // Convert to internal + user_.ids.at(id).ConvertToInternal(); - // Run + // Compute runnable + bool run = comparator_.IsIdAdded(id) ? true : comparator_.IsChanged(id); + + // Invoke generator callback const auto ¤t_id_info = user_.ids.at(id); - bool rerun = false; if (run) { - rerun = true; - } else { - const auto &previous_info = serialization_.GetLoad().internal_ids.at(id); - rerun = - internal::CheckPaths(previous_info.internal_inputs, - current_id_info.internal_inputs) != - internal::PathState::kNoChange || - internal::CheckChanged(previous_info.outputs, current_id_info.outputs); - if (!rerun && current_id_info.blob_handler != nullptr) { - rerun = current_id_info.blob_handler->CheckChanged( - previous_info.userblob, current_id_info.userblob); - } - } - - if (rerun) { dirty_ = true; - buildcc::CustomGeneratorContext ctx(command_, current_id_info.inputs, - current_id_info.outputs, - current_id_info.userblob); + CustomGeneratorContext ctx(command_, current_id_info.inputs, + current_id_info.outputs, + current_id_info.userblob); bool success = current_id_info.generate_cb(ctx); env::assert_fatal(success, fmt::format("Generate Cb failed for id {}", id)); } diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp index a6c6597b..839c91f7 100644 --- a/buildcc/lib/target/test/target/test_custom_generator.cpp +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -24,7 +24,8 @@ TEST_GROUP(CustomGeneratorTestGroup) }; // clang-format on -fs::path BUILD_DIR = fs::current_path() / "intermediate" / "custom_generator"; +const fs::path BUILD_DIR = + fs::current_path() / "intermediate" / "custom_generator"; static bool BasicGenerateCb(const buildcc::CustomGeneratorContext &ctx) { (void)ctx; @@ -33,6 +34,7 @@ static bool BasicGenerateCb(const buildcc::CustomGeneratorContext &ctx) { TEST(CustomGeneratorTestGroup, Basic) { buildcc::CustomGenerator cgen("basic", ""); + STRCMP_EQUAL(cgen.GetName().c_str(), "basic"); cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, @@ -61,265 +63,109 @@ TEST(CustomGeneratorTestGroup, Basic) { } } -TEST(CustomGeneratorTestGroup, Basic_Failure) { - buildcc::CustomGenerator cgen("basic_failure", ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, {}, - BasicGenerateCb); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - BasicGenerateCb); - cgen.Build(); - - mock().expectOneCall("BasicGenerateCb").andReturnValue(true); - mock().expectOneCall("BasicGenerateCb").andReturnValue(false); - buildcc::m::CustomGeneratorRunner(cgen); - - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); +TEST(CustomGeneratorTestGroup, BasicRebuild) { + constexpr const char *const kName = "basic_rebuild"; - // Load - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - - const auto &internal_map = serialization.GetLoad().internal_ids; - CHECK_EQUAL(internal_map.size(), 1); -} - -TEST(CustomGeneratorTestGroup, Basic_Group) { - buildcc::CustomGenerator cgen("basic_group", ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - BasicGenerateCb); - cgen.AddGroupInfo("grouped_id1_and_id2", {"id1", "id2"}); - cgen.Build(); - - mock().expectOneCall("BasicGenerateCb").andReturnValue(true); - mock().expectOneCall("BasicGenerateCb").andReturnValue(true); - buildcc::m::CustomGeneratorRunner(cgen); - - // Serialization check { - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - - const auto &internal_map = serialization.GetLoad().internal_ids; - CHECK_EQUAL(internal_map.size(), 2); - const auto &id1_info = internal_map.at("id1"); - CHECK_EQUAL(id1_info.internal_inputs.size(), 1); - CHECK_EQUAL(id1_info.outputs.size(), 1); + buildcc::CustomGenerator cgen(kName, ""); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.Build(); - const auto &id2_info = internal_map.at("id2"); - CHECK_EQUAL(id2_info.internal_inputs.size(), 1); - CHECK_EQUAL(id2_info.outputs.size(), 0); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + buildcc::m::CustomGeneratorRunner(cgen); } -} - -TEST(CustomGeneratorTestGroup, Basic_Group_Dependency) { - buildcc::CustomGenerator cgen("basic_group_dependency", ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - BasicGenerateCb); - cgen.AddGroupInfo("grouped_id1_and_id2", {"id1", "id2"}, [](auto &&task_map) { - task_map.at("id1").precede(task_map.at("id2")); - }); - cgen.Build(); - - mock().expectOneCall("BasicGenerateCb").andReturnValue(true); - mock().expectOneCall("BasicGenerateCb").andReturnValue(true); - buildcc::m::CustomGeneratorRunner(cgen); - // Serialization check { - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - - const auto &internal_map = serialization.GetLoad().internal_ids; - CHECK_EQUAL(internal_map.size(), 2); - const auto &id1_info = internal_map.at("id1"); - CHECK_EQUAL(id1_info.internal_inputs.size(), 1); - CHECK_EQUAL(id1_info.outputs.size(), 1); + buildcc::CustomGenerator cgen(kName, ""); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.Build(); - const auto &id2_info = internal_map.at("id2"); - CHECK_EQUAL(id2_info.internal_inputs.size(), 1); - CHECK_EQUAL(id2_info.outputs.size(), 0); + buildcc::m::CustomGeneratorRunner(cgen); } } -TEST(CustomGeneratorTestGroup, Basic_Group_DependencyFailure) { - buildcc::CustomGenerator cgen("basic_group_dependency_failure", ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - BasicGenerateCb); - cgen.AddGroupInfo("grouped_id1_and_id2", {"id1", "id2"}, [](auto &&task_map) { - task_map.at("id1").precede(task_map.at("id2")); - buildcc::env::assert_fatal("Failure"); - }); - cgen.Build(); - - buildcc::m::CustomGeneratorRunner(cgen); +TEST(CustomGeneratorTestGroup, BasicRebuild_Add_Remove) { + constexpr const char *const kName = "basic_rebuild_add_remove"; - // Serialization check { - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); + buildcc::CustomGenerator cgen(kName, ""); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.Build(); - const auto &internal_map = serialization.GetLoad().internal_ids; - CHECK_EQUAL(internal_map.size(), 0); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + buildcc::m::CustomGeneratorRunner(cgen); } - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); -} - -bool FailureCb(const buildcc::CustomGeneratorContext &ctx) { - (void)ctx; - return false; -} -bool SuccessCb(const buildcc::CustomGeneratorContext &ctx) { - (void)ctx; - return true; -} - -// An ungrouped task a dependency on a grouped task and fail the -// ungrouped task -TEST(CustomGeneratorTestGroup, Basic_Group_DependencyFailure2) { - buildcc::CustomGenerator cgen("basic_group_dependency_failure2", ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FailureCb); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, SuccessCb); - cgen.AddGroupInfo("grouped_id2", {"id2"}); - cgen.AddDependencyCb([&](auto &&task_map) { - task_map.at("id1").precede(task_map.at("grouped_id2")); - }); - cgen.Build(); - - buildcc::m::CustomGeneratorRunner(cgen); - - // Serialization check + // Remove { - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); + buildcc::CustomGenerator cgen(kName, ""); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + // ID2 Removed + cgen.Build(); - const auto &internal_map = serialization.GetLoad().internal_ids; - CHECK_EQUAL(internal_map.size(), 0); + buildcc::m::CustomGeneratorExpect_IdRemoved(1, &cgen); + buildcc::m::CustomGeneratorRunner(cgen); } - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); -} - -// Behaviour -// Initial: A | B -> Passes -// Changes: (GID:NEW)[A -> B] -> No rebuild triggered - -// Behaviour -// Initial: A | B -> Fails -// Changes: (GID:NEW)[A -> B] -> rebuild triggered due to previous failure - -// ! IMPORTANT -// * NOTE, It is users responsibility to make sure that when A -> B, A's data -// change should automatically trigger B - -// For example: Say A -> B i.e B depends on A -// In a typical scenario, B would depend on A's output -// To make sure B is triggered when A changes. Make sure you use A's output in -// B's userblob. -// In this way whenever A changes, B's userblob automatically becomes "newer" -// and triggers a rebuild as well - -// Say, A gives out "rebuild = true/false" as its output -// We can use this "rebuild" variable in B's userblob -// When A runs and "rebuild" changes from false to true, During the `TaskRunner` -// we check B's userblob and automatically invoke the `CheckChanged` virtual -// call -// TODO, Create a testcase for the above scenario (Advanced_DependencyRebuild -// scenario) - -// DONE, Make B fail because it properly depends on A -static bool rebuild_value{false}; -static bool ProperDependency1(const buildcc::CustomGeneratorContext &ctx) { - (void)ctx; - mock().actualCall("ProperDependency1"); - rebuild_value = true; - return true; -} - -static bool ProperDependency2(const buildcc::CustomGeneratorContext &ctx) { - (void)ctx; - mock().actualCall("ProperDependency2"); - return rebuild_value; -} - -// ProperDependency2 depends on ProperDependency1 completion -TEST(CustomGeneratorTestGroup, Basic_ProperDependency_GoodCase) { - rebuild_value = false; - - buildcc::CustomGenerator cgen("basic_proper_dependency_good_case", ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, ProperDependency1); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - ProperDependency2); - cgen.AddDependencyCb( - [](auto &&task_map) { task_map.at("id1").precede(task_map.at("id2")); }); - cgen.Build(); - - mock().expectOneCall("ProperDependency1"); - mock().expectOneCall("ProperDependency2"); - buildcc::m::CustomGeneratorRunner(cgen); - - // Serialization check + // Add { - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); + buildcc::CustomGenerator cgen(kName, ""); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, + {"{current_build_dir}/dummy_main.o"}, BasicGenerateCb); + cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, + BasicGenerateCb); + cgen.Build(); - const auto &internal_map = serialization.GetLoad().internal_ids; - CHECK_EQUAL(internal_map.size(), 2); + buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + buildcc::m::CustomGeneratorRunner(cgen); } - - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } -// ProperDependency2 depends on ProperDependency1 completion -TEST(CustomGeneratorTestGroup, Basic_ProperDependency_BadCase) { - rebuild_value = false; - - buildcc::CustomGenerator cgen("basic_proper_dependency_bad_case", ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, ProperDependency1); +TEST(CustomGeneratorTestGroup, Basic_Failure) { + buildcc::CustomGenerator cgen("basic_failure", ""); + cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, {}, + BasicGenerateCb); cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.cpp"}, {}, - ProperDependency2); - cgen.AddDependencyCb( - [](auto &&task_map) { task_map.at("id2").precede(task_map.at("id1")); }); + BasicGenerateCb); cgen.Build(); - mock().expectOneCall("ProperDependency2"); + mock().expectOneCall("BasicGenerateCb").andReturnValue(true); + mock().expectOneCall("BasicGenerateCb").andReturnValue(false); buildcc::m::CustomGeneratorRunner(cgen); - // Serialization check - { - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); + CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); - const auto &internal_map = serialization.GetLoad().internal_ids; - CHECK_EQUAL(internal_map.size(), 0); - } + // Load + buildcc::internal::CustomGeneratorSerialization serialization( + cgen.GetBinaryPath()); + CHECK_TRUE(serialization.LoadFromFile()); - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); + const auto &internal_map = serialization.GetLoad().internal_ids; + CHECK_EQUAL(internal_map.size(), 1); } TEST(CustomGeneratorTestGroup, DefaultArgumentUsage) { buildcc::CustomGenerator cgen("default_argument_usage", ""); - cgen.AddPatterns({ - {"dummy_main_c", "{current_root_dir}/dummy_main.c"}, - {"dummy_main_o", "{current_build_dir}/dummy_main.o"}, - {"dummy_main_cpp", "{current_root_dir}/dummy_main.cpp"}, - }); + cgen.AddPatterns({{"dummy_main_c", "{current_root_dir}/dummy_main.c"}, + {"dummy_main_o", "{current_build_dir}/dummy_main.o"}, + {"dummy_main_cpp", "{current_root_dir}/dummy_main.cpp"}, + {"hello", "world"}}); + STRCMP_EQUAL(cgen.ParsePattern("{hello}").c_str(), "world"); + STRCMP_EQUAL(cgen.Get("hello").c_str(), "world"); + cgen.AddIdInfo("id1", {"{dummy_main_c}"}, {"{dummy_main_o}"}, BasicGenerateCb); cgen.AddIdInfo("id2", {"{dummy_main_cpp}"}, {}, BasicGenerateCb); @@ -399,213 +245,6 @@ TEST(CustomGeneratorTestGroup, FailureCases) { buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); } -static bool Dep1Cb(const buildcc::CustomGeneratorContext &ctx) { - (void)ctx; - mock().actualCall("Dep1Cb"); - return buildcc::env::Command::Execute(""); -} - -static bool Dep2Cb(const buildcc::CustomGeneratorContext &ctx) { - (void)ctx; - mock().actualCall("Dep2Cb"); - return buildcc::env::Command::Execute(""); -} - -static void DependencyCb(std::unordered_map &&task_map) { - task_map.at("id1").precede(task_map.at("id2")); -} - -TEST(CustomGeneratorTestGroup, AddDependency_BasicCheck) { - constexpr const char *const kGenName = "add_dependency_basic_check"; - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, Dep2Cb); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, Dep1Cb); - cgen.AddDependencyCb(DependencyCb); - cgen.Build(); - - mock().expectOneCall("Dep1Cb"); - buildcc::env::m::CommandExpect_Execute(1, true); - mock().expectOneCall("Dep2Cb"); - buildcc::env::m::CommandExpect_Execute(1, true); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); - } -} - -static bool FileDep1Cb(const buildcc::CustomGeneratorContext &ctx) { - mock().actualCall("FileDep1Cb"); - for (const auto &o : ctx.outputs) { - CHECK_TRUE(buildcc::env::save_file(o.string().c_str(), "", false)); - } - return true; -} - -static bool FileDep2Cb(const buildcc::CustomGeneratorContext &ctx) { - mock().actualCall("FileDep2Cb"); - for (const auto &i : ctx.inputs) { - CHECK_TRUE(fs::exists(i)); - } - return true; -} - -TEST(CustomGeneratorTestGroup, AddDependency_FileDep) { - constexpr const char *const kGenName = "add_dependency_file_dep"; - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); - cgen.AddDependencyCb(DependencyCb); - cgen.Build(); - - mock().expectOneCall("FileDep1Cb"); - mock().expectOneCall("FileDep2Cb"); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); - } -} - -TEST(CustomGeneratorTestGroup, AddDependency_FileDep_WithRebuild) { - constexpr const char *const kGenName = "add_dependency_file_dep_with_rebuild"; - - fs::path kInputFile = - (BUILD_DIR / kGenName / "dummy_main.c").make_preferred(); - UT_PRINT(kInputFile.string().c_str()); - fs::create_directories(BUILD_DIR / kGenName); - CHECK_TRUE(buildcc::env::save_file(kInputFile.string().c_str(), "", false)); - - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); - cgen.AddDependencyCb(DependencyCb); - cgen.Build(); - - mock().expectOneCall("FileDep1Cb"); - mock().expectOneCall("FileDep2Cb"); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); - - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); - } - - // Same, no change - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); - cgen.AddDependencyCb(DependencyCb); - cgen.Build(); - - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); - - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); - } - - // reset - fs::remove_all(BUILD_DIR / kGenName / "dummy_main.o"); - - // Remove id1, should cause id2 to fail - // NOTE, dirty_ == false is not made true when id2 is run, however id removed - // sets dirty_ == true - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); - cgen.AddDependencyCb(DependencyCb); - cgen.Build(); - - buildcc::m::CustomGeneratorExpect_IdRemoved(1, &cgen); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 0); - - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); - } - - // reset - buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); - fs::remove_all(BUILD_DIR / kGenName / "dummy_main.o"); - - // Added - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); - cgen.AddDependencyCb(DependencyCb); - cgen.Build(); - - buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); - buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); - mock().expectOneCall("FileDep1Cb"); - mock().expectOneCall("FileDep2Cb"); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); - - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); - } - - // reset - buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); - fs::remove_all(BUILD_DIR / kGenName / "dummy_main.o"); - - buildcc::m::blocking_sleep(1); - buildcc::env::save_file(kInputFile.string().c_str(), "", false); - - // Update id1:dummy_main.c -> updated dummy_main.o -> should rerun id2 as well - { - buildcc::CustomGenerator cgen(kGenName, ""); - - cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, FileDep1Cb); - cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.o"}, {}, FileDep2Cb); - cgen.AddDependencyCb(DependencyCb); - cgen.Build(); - - mock().expectOneCall("FileDep1Cb"); - mock().expectOneCall("FileDep2Cb"); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); - - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); - } - - buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); -} - static bool RealGenerateCb(const buildcc::CustomGeneratorContext &ctx) { (void)ctx; mock().actualCall("RealGenerateCb"); @@ -666,209 +305,6 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Basic) { buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); } -TEST(CustomGeneratorTestGroup, RealGenerate_RemoveAndAdd) { - constexpr const char *const kGenName = "real_generator_remove_and_add"; - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.Build(); - - mock().expectOneCall("RealGenerateCb"); - buildcc::env::m::CommandExpect_Execute(1, true); - mock().expectOneCall("RealGenerateCb"); - buildcc::env::m::CommandExpect_Execute(1, true); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); - auto imap = serialization.GetLoad().internal_ids; - CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); - - CHECK_EQUAL(imap.at("id1").outputs.size(), 1); - CHECK_EQUAL(imap.at("id2").outputs.size(), 1); - } - - // Same, no change - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.Build(); - - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); - auto imap = serialization.GetLoad().internal_ids; - CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); - - CHECK_EQUAL(imap.at("id1").outputs.size(), 1); - CHECK_EQUAL(imap.at("id2").outputs.size(), 1); - } - - // Map Removed - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - - cgen.Build(); - - buildcc::m::CustomGeneratorExpect_IdRemoved(1, &cgen); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 1); - auto imap = serialization.GetLoad().internal_ids; - CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id1").outputs.size(), 1); - - CHECK_THROWS(std::out_of_range, imap.at("id2")); - } - - // Map Added Failure - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddDependencyCb([](auto &&task_map) { - task_map.at("id1").precede(task_map.at("id2")); - }); - cgen.Build(); - - buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); - mock().expectOneCall("RealGenerateCb"); - buildcc::env::m::CommandExpect_Execute(1, false); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 1); - auto imap = serialization.GetLoad().internal_ids; - CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id1").outputs.size(), 1); - CHECK_THROWS(std::out_of_range, imap.at("id2")); - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); - } - - buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); - - // Map Added Success - { - buildcc::CustomGenerator cgen(kGenName, ""); - cgen.AddIdInfo("id1", {"{current_root_dir}/dummy_main.cpp"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddIdInfo("id2", {"{current_root_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.Build(); - - buildcc::m::CustomGeneratorExpect_IdAdded(1, &cgen); - mock().expectOneCall("RealGenerateCb"); - buildcc::env::m::CommandExpect_Execute(1, true); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); - auto imap = serialization.GetLoad().internal_ids; - CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); - - CHECK_EQUAL(imap.at("id1").outputs.size(), 1); - CHECK_EQUAL(imap.at("id2").outputs.size(), 1); - } -} - -TEST(CustomGeneratorTestGroup, RealGenerate_Update_Failure) { - constexpr const char *const kGenName = "real_generator_update_failure"; - - { - buildcc::CustomGenerator cgen(kGenName, ""); - buildcc::env::save_file( - (cgen.GetBuildDir() / "dummy_main.c").string().c_str(), "", false); - buildcc::env::save_file( - (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); - - cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, - {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); - cgen.AddDependencyCb([](auto &&task_map) { - task_map.at("id1").precede(task_map.at("id2")); - }); - cgen.Build(); - - mock().expectOneCall("RealGenerateCb"); - buildcc::env::m::CommandExpect_Execute(1, true); - mock().expectOneCall("RealGenerateCb"); - buildcc::env::m::CommandExpect_Execute(1, true); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); - auto imap = serialization.GetLoad().internal_ids; - CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); - - CHECK_EQUAL(imap.at("id1").outputs.size(), 1); - CHECK_EQUAL(imap.at("id2").outputs.size(), 1); - } - - buildcc::m::blocking_sleep(1); - - // Updated Input file Failure - UT_PRINT("Updated Input file: Failure\r\n"); - { - buildcc::CustomGenerator cgen(kGenName, ""); - buildcc::env::save_file( - (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); - - cgen.AddIdInfo("id1", {"{current_build_dir}/dummy_main.c"}, - {"{current_build_dir}/dummy_main.o"}, RealGenerateCb); - cgen.AddIdInfo("id2", {"{current_build_dir}/dummy_main.cpp"}, - {"{current_build_dir}/other_dummy_main.o"}, RealGenerateCb); - cgen.AddDependencyCb([](auto &&task_map) { - task_map.at("id1").precede(task_map.at("id2")); - }); - cgen.Build(); - - mock().expectOneCall("RealGenerateCb"); - buildcc::env::m::CommandExpect_Execute(1, false); - buildcc::m::CustomGeneratorRunner(cgen); - - buildcc::internal::CustomGeneratorSerialization serialization( - cgen.GetBinaryPath()); - CHECK_TRUE(serialization.LoadFromFile()); - CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 1); - auto imap = serialization.GetLoad().internal_ids; - CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id1").outputs.size(), 1); - - CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::FAILURE); - } - - buildcc::env::set_task_state(buildcc::env::TaskState::SUCCESS); -} - TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { constexpr const char *const kGenName = "real_generator_update_success"; diff --git a/buildcc/schema/include/schema/custom_generator_schema.h b/buildcc/schema/include/schema/custom_generator_schema.h index 0a171f2c..d7027b98 100644 --- a/buildcc/schema/include/schema/custom_generator_schema.h +++ b/buildcc/schema/include/schema/custom_generator_schema.h @@ -27,11 +27,9 @@ struct CustomGeneratorSchema { private: static constexpr const char *const kName = "name"; static constexpr const char *const kIds = "ids"; - static constexpr const char *const kGroups = "groups"; public: using IdKey = std::string; - using GroupKey = std::string; struct IdInfo { private: static constexpr const char *const kInputs = "inputs"; @@ -57,23 +55,18 @@ struct CustomGeneratorSchema { }; using IdPair = std::pair; - using GroupInfo = std::unordered_set; - using GroupPair = std::pair; std::string name; std::unordered_map internal_ids; - std::unordered_map internal_groups; friend void to_json(json &j, const CustomGeneratorSchema &schema) { j[kName] = schema.name; j[kIds] = schema.internal_ids; - j[kGroups] = schema.internal_groups; } friend void from_json(const json &j, CustomGeneratorSchema &schema) { j.at(kName).get_to(schema.name); j.at(kIds).get_to(schema.internal_ids); - j.at(kGroups).get_to(schema.internal_groups); } }; diff --git a/cmake/coverage/gcovr.cmake b/cmake/coverage/gcovr.cmake index d127fe42..4d97ebbe 100644 --- a/cmake/coverage/gcovr.cmake +++ b/cmake/coverage/gcovr.cmake @@ -9,6 +9,7 @@ else() message("GCOVR at ${gcovr_program}") set(GCOVR_REMOVE_OPTIONS + --exclude "(.+/)?third_party(.+/)?" --exclude "(.+/)?spdlog(.+/)?" --exclude "(.+/)?fmt(.+/)?" --exclude "(.+/)?taskflow(.+/)?" diff --git a/cmake/tool/cppcheck.cmake b/cmake/tool/cppcheck.cmake index 20d98554..9f11dbe6 100644 --- a/cmake/tool/cppcheck.cmake +++ b/cmake/tool/cppcheck.cmake @@ -13,7 +13,7 @@ if(${BUILDCC_CPPCHECK}) set(CPPCHECK_ADDITIONAL_OPTIONS --std=c++17 -q - --error-exitcode=1 + # --error-exitcode=1 --cppcheck-build-dir=${CMAKE_CURRENT_BINARY_DIR}/cppcheck_output ) set(CPPCHECK_CHECK_DIR From d261a33f687c4c6d55ceef3aa18ee57d86590fd8 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Fri, 2 Dec 2022 12:24:41 -0800 Subject: [PATCH 33/35] [Enhancement] Path Serialization (#228) --- .../target/include/target/custom_generator.h | 120 +------- .../custom_generator/custom_blob_handler.h | 48 ++++ .../custom_generator_context.h | 11 +- .../src/custom_generator/custom_generator.cpp | 263 +++++++++++++----- .../target/src/generator/file_generator.cpp | 41 +-- .../test/target/test_custom_generator.cpp | 46 +-- .../include/schema/custom_generator_schema.h | 8 +- buildcc/schema/include/schema/path.h | 154 ++++++++++ 8 files changed, 437 insertions(+), 254 deletions(-) diff --git a/buildcc/lib/target/include/target/custom_generator.h b/buildcc/lib/target/include/target/custom_generator.h index 0712cde5..a9dec033 100644 --- a/buildcc/lib/target/include/target/custom_generator.h +++ b/buildcc/lib/target/include/target/custom_generator.h @@ -39,29 +39,25 @@ namespace buildcc { struct UserCustomGeneratorSchema : public internal::CustomGeneratorSchema { struct UserIdInfo : internal::CustomGeneratorSchema::IdInfo { - fs_unordered_set inputs; // TODO, Remove - GenerateCb generate_cb; - std::shared_ptr blob_handler{nullptr}; - void ConvertToInternal() { - internal_inputs = internal::path_schema_convert( - inputs, internal::Path::CreateExistingPath); + inputs.ComputeHashForAll(); userblob = blob_handler != nullptr ? blob_handler->GetSerializedData() : std::vector(); } - }; - using UserIdPair = std::pair; - std::unordered_map ids; + GenerateCb generate_cb; + std::shared_ptr blob_handler{nullptr}; + }; void ConvertToInternal() { for (auto &[id_key, id_info] : ids) { - id_info.internal_inputs = path_schema_convert( - id_info.inputs, internal::Path::CreateExistingPath); + id_info.ConvertToInternal(); auto [_, success] = internal_ids.try_emplace(id_key, id_info); env::assert_fatal(success, fmt::format("Could not save {}", id_key)); } } + + std::unordered_map ids; }; class CustomGenerator : public internal::BuilderInterface { @@ -69,8 +65,8 @@ class CustomGenerator : public internal::BuilderInterface { CustomGenerator(const std::string &name, const TargetEnv &env) : name_(name), env_(env.GetTargetRootDir(), env.GetTargetBuildDir() / name), - serialization_(env_.GetTargetBuildDir() / fmt::format("{}.json", name)), - comparator_(serialization_.GetLoad(), user_) { + serialization_(env_.GetTargetBuildDir() / + fmt::format("{}.json", name)) { Initialize(); } virtual ~CustomGenerator() = default; @@ -115,100 +111,9 @@ class CustomGenerator : public internal::BuilderInterface { const fs::path &GetBuildDir() const { return env_.GetTargetBuildDir(); } const std::string &Get(const std::string &file_identifier) const; -private: - struct Comparator { - Comparator(const internal::CustomGeneratorSchema &loaded, - const UserCustomGeneratorSchema &us) - : loaded_schema_(loaded), current_schema_(us) {} - - enum class State { - kRemoved, - kAdded, - kCheckLater, - }; - - void AddAllIds() { - const auto &curr_ids = current_schema_.ids; - for (const auto &[id, _] : curr_ids) { - id_state_info_.at(State::kAdded).insert(id); - } - } - - void CompareIds() { - const auto &prev_ids = loaded_schema_.internal_ids; - const auto &curr_ids = current_schema_.ids; - - for (const auto &[prev_id, _] : prev_ids) { - if (curr_ids.find(prev_id) == curr_ids.end()) { - // Id Removed condition, previous id is not present in the current run - id_state_info_.at(State::kRemoved).insert(prev_id); - } - } - - for (const auto &[curr_id, _] : curr_ids) { - if (prev_ids.find(curr_id) == prev_ids.end()) { - // Id Added condition - id_state_info_.at(State::kAdded).insert(curr_id); - } else { - // Id Check Later condition - id_state_info_.at(State::kCheckLater).insert(curr_id); - } - } - } - - bool IsChanged(const std::string &id) const { - const auto &previous_id_info = loaded_schema_.internal_ids.at(id); - const auto ¤t_id_info = current_schema_.ids.at(id); - - bool changed = internal::CheckPaths(previous_id_info.internal_inputs, - current_id_info.internal_inputs) != - internal::PathState::kNoChange; - changed = changed || internal::CheckChanged(previous_id_info.outputs, - current_id_info.outputs); - if (!changed && current_id_info.blob_handler != nullptr) { - // We only check blob handler if not changed by inputs/outputs - // Checking blob_handler could be expensive so this optimization is made - // to run only when changed == false - changed = current_id_info.blob_handler->CheckChanged( - previous_id_info.userblob, current_id_info.userblob); - } - return changed; - } - - const std::unordered_set &GetRemovedIds() const { - return id_state_info_.at(State::kRemoved); - } - - const std::unordered_set &GetAddedIds() const { - return id_state_info_.at(State::kAdded); - } - - const std::unordered_set &GetCheckLaterIds() const { - return id_state_info_.at(State::kCheckLater); - } - - bool IsIdAdded(const std::string &id) const { - return id_state_info_.at(State::kAdded).count(id) == 1; - } - - private: - const internal::CustomGeneratorSchema &loaded_schema_; - const UserCustomGeneratorSchema ¤t_schema_; - std::unordered_map> id_state_info_{ - {State::kRemoved, std::unordered_set()}, - {State::kAdded, std::unordered_set()}, - {State::kCheckLater, std::unordered_set()}, - }; - }; - private: void Initialize(); - - tf::Task CreateTaskRunner(tf::Subflow &subflow, const std::string &id); - void TaskRunner(const std::string &id); - void GenerateTask(); - void BuildGenerate(); // Recheck states void IdRemoved(); @@ -227,13 +132,6 @@ class CustomGenerator : public internal::BuilderInterface { // Serialization UserCustomGeneratorSchema user_; - // Comparator - Comparator comparator_; - - std::mutex success_schema_mutex_; - std::unordered_map - success_schema_; - // Internal env::Command command_; }; diff --git a/buildcc/lib/target/include/target/custom_generator/custom_blob_handler.h b/buildcc/lib/target/include/target/custom_generator/custom_blob_handler.h index 1c268301..3b64d23c 100644 --- a/buildcc/lib/target/include/target/custom_generator/custom_blob_handler.h +++ b/buildcc/lib/target/include/target/custom_generator/custom_blob_handler.h @@ -23,6 +23,12 @@ namespace buildcc { +/** + * @brief Abstract class for serializing additional data for which rebuilds + * might be triggered i.e data that is not input/output files + * TODO, Add examples here + * + */ class CustomBlobHandler { public: CustomBlobHandler() = default; @@ -54,6 +60,48 @@ class CustomBlobHandler { virtual std::vector Serialize() const = 0; }; +/** + * @brief Typed Custom Blob handler which automatically performs Serialization + * and Deserialization as long as it is JSON serializable + * + * NOTE: Type data is stored as a reference (to avoid copying large amount of + * data) when constructing TypedCustomBlobHandler + * + * @tparam Type should be JSON serializable (see nlohmann::json compatible + * objects) + */ +template +class TypedCustomBlobHandler : public CustomBlobHandler { +public: + explicit TypedCustomBlobHandler(const Type &data) : data_(data) {} + + // serialized_data has already been verified + static Type Deserialize(const std::vector &serialized_data) { + json j = json::from_msgpack(serialized_data, true, false); + Type deserialized; + j.get_to(deserialized); + return deserialized; + } + +private: + const Type &data_; + + bool Verify(const std::vector &serialized_data) const override { + json j = json::from_msgpack(serialized_data, true, false); + return !j.is_discarded(); + } + + bool IsEqual(const std::vector &previous, + const std::vector ¤t) const override { + return Deserialize(previous) == Deserialize(current); + } + + std::vector Serialize() const override { + json j = data_; + return json::to_msgpack(j); + } +}; + } // namespace buildcc #endif diff --git a/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h b/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h index 207015d9..4c49d5ff 100644 --- a/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h +++ b/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h @@ -25,19 +25,20 @@ namespace buildcc { class CustomGeneratorContext { public: - CustomGeneratorContext(const env::Command &c, const fs_unordered_set &i, - const fs_unordered_set &o, + CustomGeneratorContext(const env::Command &c, + const std::unordered_set &i, + const std::unordered_set &o, const std::vector &ub) : command(c), inputs(i), outputs(o), userblob(ub) {} const env::Command &command; - const fs_unordered_set &inputs; - const fs_unordered_set &outputs; + const std::unordered_set &inputs; + const std::unordered_set &outputs; const std::vector &userblob; }; // clang-format off -using GenerateCb = std::function; +using GenerateCb = std::function; // clang-format on } // namespace buildcc diff --git a/buildcc/lib/target/src/custom_generator/custom_generator.cpp b/buildcc/lib/target/src/custom_generator/custom_generator.cpp index b60283e8..138bb9f3 100644 --- a/buildcc/lib/target/src/custom_generator/custom_generator.cpp +++ b/buildcc/lib/target/src/custom_generator/custom_generator.cpp @@ -28,6 +28,164 @@ constexpr const char *const kCurrentBuildDirName = "current_build_dir"; namespace buildcc { +struct Comparator { + Comparator(const internal::CustomGeneratorSchema &loaded, + const UserCustomGeneratorSchema ¤t) + : loaded_(loaded), current_(current) {} + + enum class State { + kRemoved, + kAdded, + kCheckLater, + }; + + void AddAllIds() { + const auto &curr_ids = current_.ids; + for (const auto &[id, _] : curr_ids) { + id_state_info_.at(State::kAdded).insert(id); + } + } + + void CompareAndAddIds() { + const auto &prev_ids = loaded_.internal_ids; + const auto &curr_ids = current_.ids; + + for (const auto &[prev_id, _] : prev_ids) { + if (curr_ids.find(prev_id) == curr_ids.end()) { + // Id Removed condition, previous id is not present in the current run + id_state_info_.at(State::kRemoved).insert(prev_id); + } + } + + for (const auto &[curr_id, _] : curr_ids) { + if (prev_ids.find(curr_id) == prev_ids.end()) { + // Id Added condition + id_state_info_.at(State::kAdded).insert(curr_id); + } else { + // Id Check Later condition + id_state_info_.at(State::kCheckLater).insert(curr_id); + } + } + } + + bool IsChanged(const std::string &id) const { + const auto &previous_id_info = loaded_.internal_ids.at(id); + const auto ¤t_id_info = current_.ids.at(id); + + bool changed = !previous_id_info.inputs.IsEqual(current_id_info.inputs) || + !previous_id_info.outputs.IsEqual(current_id_info.outputs); + if (!changed && current_id_info.blob_handler != nullptr) { + // We only check blob handler if not changed by inputs/outputs + // Checking blob_handler could be expensive so this optimization is made + // to run only when changed == false + changed = current_id_info.blob_handler->CheckChanged( + previous_id_info.userblob, current_id_info.userblob); + } + return changed; + } + + const std::unordered_set &GetRemovedIds() const { + return id_state_info_.at(State::kRemoved); + } + + const std::unordered_set &GetAddedIds() const { + return id_state_info_.at(State::kAdded); + } + + const std::unordered_set &GetCheckLaterIds() const { + return id_state_info_.at(State::kCheckLater); + } + + bool IsIdAdded(const std::string &id) const { + return id_state_info_.at(State::kAdded).count(id) == 1; + } + +private: + const buildcc::internal::CustomGeneratorSchema &loaded_; + const buildcc::UserCustomGeneratorSchema ¤t_; + std::unordered_map> id_state_info_{ + {State::kRemoved, std::unordered_set()}, + {State::kAdded, std::unordered_set()}, + {State::kCheckLater, std::unordered_set()}, + }; +}; + +struct TaskState { + bool should_run{false}; + bool run_success{false}; +}; + +struct TaskFunctor { + TaskFunctor(const std::string &id, + UserCustomGeneratorSchema::UserIdInfo &id_info, + const Comparator &comparator, const env::Command &command, + TaskState &state) + : id_(id), id_info_(id_info), comparator(comparator), command_(command), + state_(state) {} + + void operator()() { + if (env::get_task_state() != env::TaskState::SUCCESS) { + return; + } + try { + id_info_.ConvertToInternal(); + // Compute runnable + state_.should_run = + comparator.IsIdAdded(id_) ? true : comparator.IsChanged(id_); + + // Invoke generator callback + if (state_.should_run) { + const auto input_paths = id_info_.inputs.GetPaths(); + CustomGeneratorContext ctx(command_, input_paths, + id_info_.outputs.GetPaths(), + id_info_.userblob); + + bool success = id_info_.generate_cb(ctx); + env::assert_fatal(success, + fmt::format("Generate Cb failed for id {}", id_)); + } + state_.run_success = true; + } catch (...) { + env::set_task_state(env::TaskState::FAILURE); + } + } + +private: + const std::string &id_; + UserCustomGeneratorSchema::UserIdInfo &id_info_; + + const Comparator &comparator; + const env::Command &command_; + + TaskState &state_; +}; + +bool ComputeBuild(const internal::CustomGeneratorSerialization &serialization, + Comparator &comparator, + std::function &&id_removed_cb, + std::function &&id_added_cb) { + bool build = false; + if (!serialization.IsLoaded()) { + comparator.AddAllIds(); + build = true; + } else { + comparator.CompareAndAddIds(); + const bool is_removed = !comparator.GetRemovedIds().empty(); + const bool is_added = !comparator.GetAddedIds().empty(); + build = is_removed || is_added; + + if (is_removed) { + id_removed_cb(); + } + + for (const auto &id : comparator.GetAddedIds()) { + (void)id; + id_added_cb(); + } + } + return build; +} + void CustomGenerator::AddPattern(const std::string &identifier, const std::string &pattern) { command_.AddDefaultArgument(identifier, command_.Construct(pattern)); @@ -62,12 +220,12 @@ void CustomGenerator::AddIdInfo( UserCustomGeneratorSchema::UserIdInfo schema; for (const auto &i : inputs) { - fs::path input = string_as_path(command_.Construct(i)); - schema.inputs.emplace(std::move(input)); + auto input = command_.Construct(i); + schema.inputs.Emplace(input, ""); } for (const auto &o : outputs) { - fs::path output = string_as_path(command_.Construct(o)); - schema.outputs.emplace(std::move(output)); + auto output = command_.Construct(o); + schema.outputs.Emplace(output); } schema.generate_cb = generate_cb; schema.blob_handler = blob_handler; @@ -76,7 +234,6 @@ void CustomGenerator::AddIdInfo( void CustomGenerator::Build() { (void)serialization_.LoadFromFile(); - GenerateTask(); } @@ -101,29 +258,6 @@ void CustomGenerator::Initialize() { tf_.name(name_); } -void CustomGenerator::BuildGenerate() { - if (!serialization_.IsLoaded()) { - comparator_.AddAllIds(); - dirty_ = true; - } else { - // For IDS - comparator_.CompareIds(); - - const bool is_removed = !comparator_.GetRemovedIds().empty(); - const bool is_added = !comparator_.GetAddedIds().empty(); - dirty_ = is_removed || is_added; - - if (is_removed) { - IdRemoved(); - } - - for (const auto &id : comparator_.GetAddedIds()) { - (void)id; - IdAdded(); - } - } -} - void CustomGenerator::GenerateTask() { tf::Task generate_task = tf_.emplace([&](tf::Subflow &subflow) { if (env::get_task_state() != env::TaskState::SUCCESS) { @@ -132,29 +266,43 @@ void CustomGenerator::GenerateTask() { try { // Selected ids for build - BuildGenerate(); + Comparator comparator(serialization_.GetLoad(), user_); + dirty_ = ComputeBuild( + serialization_, comparator, [this]() { IdRemoved(); }, + [this]() { IdAdded(); }); + + std::unordered_map states; // Create runner for each added/updated id - for (const auto &id : comparator_.GetAddedIds()) { - auto task = CreateTaskRunner(subflow, id); - task.name(id); + for (const auto &id : comparator.GetAddedIds()) { + states.try_emplace(id, TaskState()); + auto &id_info = user_.ids.at(id); + TaskFunctor functor(id, id_info, comparator, command_, states.at(id)); + subflow.emplace(functor).name(id); } - for (const auto &id : comparator_.GetCheckLaterIds()) { - auto task = CreateTaskRunner(subflow, id); - task.name(id); + for (const auto &id : comparator.GetCheckLaterIds()) { + states.try_emplace(id, TaskState()); + auto &id_info = user_.ids.at(id); + TaskFunctor functor(id, id_info, comparator, command_, states.at(id)); + subflow.emplace(functor).name(id); } // NOTE, Do not call detach otherwise this will fail subflow.join(); + UserCustomGeneratorSchema user_final_schema; + for (const auto &[id, state] : states) { + dirty_ = dirty_ || state.should_run; + if (state.run_success) { + user_final_schema.ids.try_emplace(id, user_.ids.at(id)); + } + } + // Store if (dirty_) { - UserCustomGeneratorSchema user_final_schema; - user_final_schema.ids.insert(success_schema_.begin(), - success_schema_.end()); - user_final_schema.ConvertToInternal(); + serialization_.UpdateStore(user_final_schema); env::assert_fatal(serialization_.StoreToFile(), fmt::format("Store failed for {}", name_)); @@ -163,44 +311,7 @@ void CustomGenerator::GenerateTask() { env::set_task_state(env::TaskState::FAILURE); } }); - // TODO, Instead of "Generate" name the task of user's choice generate_task.name(kGenerateTaskName); } -tf::Task CustomGenerator::CreateTaskRunner(tf::Subflow &subflow, - const std::string &id) { - return subflow.emplace([&, id]() { - if (env::get_task_state() != env::TaskState::SUCCESS) { - return; - } - try { - TaskRunner(id); - } catch (...) { - env::set_task_state(env::TaskState::FAILURE); - } - }); -} - -void CustomGenerator::TaskRunner(const std::string &id) { - // Convert to internal - user_.ids.at(id).ConvertToInternal(); - - // Compute runnable - bool run = comparator_.IsIdAdded(id) ? true : comparator_.IsChanged(id); - - // Invoke generator callback - const auto ¤t_id_info = user_.ids.at(id); - if (run) { - dirty_ = true; - CustomGeneratorContext ctx(command_, current_id_info.inputs, - current_id_info.outputs, - current_id_info.userblob); - bool success = current_id_info.generate_cb(ctx); - env::assert_fatal(success, fmt::format("Generate Cb failed for id {}", id)); - } - - std::scoped_lock guard(success_schema_mutex_); - success_schema_.try_emplace(id, current_id_info); -} - } // namespace buildcc diff --git a/buildcc/lib/target/src/generator/file_generator.cpp b/buildcc/lib/target/src/generator/file_generator.cpp index 5cdb592f..3256ad2b 100644 --- a/buildcc/lib/target/src/generator/file_generator.cpp +++ b/buildcc/lib/target/src/generator/file_generator.cpp @@ -22,44 +22,12 @@ namespace { -class FileGeneratorBlobHandler : public buildcc::CustomBlobHandler { -public: - explicit FileGeneratorBlobHandler(const std::vector &commands) - : commands_(commands) {} - - // serialized_data has already been verified - static std::vector - Deserialize(const std::vector &serialized_data) { - json j = json::from_msgpack(serialized_data, true, false); - std::vector deserialized; - j.get_to(deserialized); - return deserialized; - } - -private: - const std::vector &commands_; - - bool Verify(const std::vector &serialized_data) const override { - json j = json::from_msgpack(serialized_data, true, false); - return !j.is_discarded(); - } - - bool IsEqual(const std::vector &previous, - const std::vector ¤t) const override { - return Deserialize(previous) == Deserialize(current); - } - - std::vector Serialize() const override { - json j = commands_; - return json::to_msgpack(j); - } -}; - bool FileGeneratorGenerateCb(const buildcc::CustomGeneratorContext &ctx) { (void)ctx; bool success = true; std::vector commands = - FileGeneratorBlobHandler::Deserialize(ctx.userblob); + buildcc::TypedCustomBlobHandler>::Deserialize( + ctx.userblob); for (const auto &c : commands) { bool executed = buildcc::env::Command::Execute(c); if (!executed) { @@ -92,8 +60,11 @@ void FileGenerator::AddCommand( } void FileGenerator::Build() { + auto file_blob_handler = + std::make_shared>>( + commands_); AddIdInfo("Generate", inputs_, outputs_, FileGeneratorGenerateCb, - std::make_shared(commands_)); + file_blob_handler); this->CustomGenerator::Build(); } diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp index 839c91f7..f4293c9f 100644 --- a/buildcc/lib/target/test/target/test_custom_generator.cpp +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -54,12 +54,12 @@ TEST(CustomGeneratorTestGroup, Basic) { const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 2); const auto &id1_info = internal_map.at("id1"); - CHECK_EQUAL(id1_info.internal_inputs.size(), 1); - CHECK_EQUAL(id1_info.outputs.size(), 1); + CHECK_EQUAL(id1_info.inputs.GetPathInfos().size(), 1); + CHECK_EQUAL(id1_info.outputs.GetPaths().size(), 1); const auto &id2_info = internal_map.at("id2"); - CHECK_EQUAL(id2_info.internal_inputs.size(), 1); - CHECK_EQUAL(id2_info.outputs.size(), 0); + CHECK_EQUAL(id2_info.inputs.GetPathInfos().size(), 1); + CHECK_EQUAL(id2_info.outputs.GetPaths().size(), 0); } } @@ -184,12 +184,12 @@ TEST(CustomGeneratorTestGroup, DefaultArgumentUsage) { const auto &internal_map = serialization.GetLoad().internal_ids; CHECK_EQUAL(internal_map.size(), 2); const auto &id1_info = internal_map.at("id1"); - CHECK_EQUAL(id1_info.internal_inputs.size(), 1); - CHECK_EQUAL(id1_info.outputs.size(), 1); + CHECK_EQUAL(id1_info.inputs.GetPathInfos().size(), 1); + CHECK_EQUAL(id1_info.outputs.GetPaths().size(), 1); const auto &id2_info = internal_map.at("id2"); - CHECK_EQUAL(id2_info.internal_inputs.size(), 1); - CHECK_EQUAL(id2_info.outputs.size(), 0); + CHECK_EQUAL(id2_info.inputs.GetPathInfos().size(), 1); + CHECK_EQUAL(id2_info.outputs.GetPaths().size(), 0); } } @@ -332,11 +332,11 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { CHECK_TRUE(serialization.LoadFromFile()); CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); auto imap = serialization.GetLoad().internal_ids; - CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); + CHECK_EQUAL(imap.at("id1").inputs.GetPathInfos().size(), 1); + CHECK_EQUAL(imap.at("id2").inputs.GetPathInfos().size(), 1); - CHECK_EQUAL(imap.at("id1").outputs.size(), 1); - CHECK_EQUAL(imap.at("id2").outputs.size(), 1); + CHECK_EQUAL(imap.at("id1").outputs.GetPaths().size(), 1); + CHECK_EQUAL(imap.at("id2").outputs.GetPaths().size(), 1); } buildcc::m::blocking_sleep(1); @@ -348,7 +348,7 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { buildcc::env::save_file( (cgen.GetBuildDir() / "dummy_main.cpp").string().c_str(), "", false); - std::uint64_t last_write_timestamp = static_cast( + auto last_write_timestamp = static_cast( fs::last_write_time(cgen.GetBuildDir() / "dummy_main.cpp") .time_since_epoch() .count()); @@ -368,14 +368,14 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { CHECK_TRUE(serialization.LoadFromFile()); CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); auto imap = serialization.GetLoad().internal_ids; - CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + CHECK_EQUAL(imap.at("id1").inputs.GetPathInfos().size(), 1); + CHECK_EQUAL(imap.at("id1").outputs.GetPaths().size(), 1); - CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id2").outputs.size(), 1); + CHECK_EQUAL(imap.at("id2").inputs.GetPathInfos().size(), 1); + CHECK_EQUAL(imap.at("id2").outputs.GetPaths().size(), 1); - CHECK_EQUAL(last_write_timestamp, - imap.at("id2").internal_inputs.begin()->last_write_timestamp); + STRCMP_EQUAL(std::to_string(last_write_timestamp).c_str(), + imap.at("id2").inputs.GetPathInfos().begin()->second.c_str()); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } @@ -400,11 +400,11 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { CHECK_TRUE(serialization.LoadFromFile()); CHECK_EQUAL(serialization.GetLoad().internal_ids.size(), 2); auto imap = serialization.GetLoad().internal_ids; - CHECK_EQUAL(imap.at("id1").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id1").outputs.size(), 1); + CHECK_EQUAL(imap.at("id1").inputs.GetPathInfos().size(), 1); + CHECK_EQUAL(imap.at("id1").outputs.GetPaths().size(), 1); - CHECK_EQUAL(imap.at("id2").internal_inputs.size(), 1); - CHECK_EQUAL(imap.at("id2").outputs.size(), 1); + CHECK_EQUAL(imap.at("id2").inputs.GetPathInfos().size(), 1); + CHECK_EQUAL(imap.at("id2").outputs.GetPaths().size(), 1); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } diff --git a/buildcc/schema/include/schema/custom_generator_schema.h b/buildcc/schema/include/schema/custom_generator_schema.h index d7027b98..a4088a66 100644 --- a/buildcc/schema/include/schema/custom_generator_schema.h +++ b/buildcc/schema/include/schema/custom_generator_schema.h @@ -37,18 +37,18 @@ struct CustomGeneratorSchema { static constexpr const char *const kUserblob = "userblob"; public: - path_unordered_set internal_inputs; - fs_unordered_set outputs; + PathInfoList inputs; + PathList outputs; std::vector userblob; friend void to_json(json &j, const IdInfo &info) { - j[kInputs] = info.internal_inputs; + j[kInputs] = info.inputs; j[kOutputs] = info.outputs; j[kUserblob] = info.userblob; } friend void from_json(const json &j, IdInfo &info) { - j.at(kInputs).get_to(info.internal_inputs); + j.at(kInputs).get_to(info.inputs); j.at(kOutputs).get_to(info.outputs); j.at(kUserblob).get_to(info.userblob); } diff --git a/buildcc/schema/include/schema/path.h b/buildcc/schema/include/schema/path.h index 755fa6db..9e1107d3 100644 --- a/buildcc/schema/include/schema/path.h +++ b/buildcc/schema/include/schema/path.h @@ -34,6 +34,7 @@ using json = nlohmann::ordered_json; namespace buildcc::internal { +// TODO, Update this struct Path { private: static constexpr const char *const kPathName = "path"; @@ -92,6 +93,43 @@ struct Path { return pathname == other_pathname; } + /** + * @brief Sanitizes a fs::path or std::string to a standard path string + * - Converts backslash (\) to forward slash (/) + * - Makes fs::lexically_normal (see std::filesystem library impl) + * + * @param str User provided fs::path/std::string + * @return std::string Sanitized path as std::string + */ + static std::string ToPathString(const std::string &str) { + auto path_str = str; + std::replace(path_str.begin(), path_str.end(), '\\', '/'); + path_str = fs::path(path_str).lexically_normal().string(); + return path_str; + } + + /** + * @brief Formats a fs::path or std::string for display + * - All the sanitization as done in `ToPathString` + * Additionally + * - Adds quotation marks ("") when a space is detected + * For example: test/hello world/ -> "test/hello world/" + * + * NOTE: Use this API only in places where you would like to output to + * console/run or create command through subprocess + * + * @param str User provided fs::path/std::string + * @return std::string Sanitized path as std::string for display + */ + static std::string ToPathDisplayString(const std::string &str) { + auto path_str = ToPathString(str); + // if spaces are present in the path string, surround this with brackets + if (path_str.find(' ') != std::string::npos) { + path_str = fmt::format("\"{}\"", path_str); + } + return path_str; + } + // JSON specialization friend void to_json(json &j, const Path &p) { @@ -124,6 +162,7 @@ struct Path { std::uint64_t last_write_timestamp{0}; }; +// TODO, Remove this // Used by Path class PathHash { public: @@ -132,9 +171,122 @@ class PathHash { size_t operator()(const fs::path &p) const { return fs::hash_value(p); } }; +// TODO, Remove this using path_unordered_set = std::unordered_set; using fs_unordered_set = std::unordered_set; +/** + * @brief Stores path + */ +class PathList { +public: + PathList() = default; + PathList(std::initializer_list paths) { + for (const auto &path : paths) { + Emplace(path); + } + } + + void Emplace(const std::string &pstr) { + auto path_str = Path::ToPathString(pstr); + paths_.emplace(std::move(path_str)); + } + + bool IsEqual(const PathList &other) const { return paths_ == other.paths_; } + const std::unordered_set &GetPaths() const { return paths_; } + + friend void to_json(json &j, const PathList &plist) { j = plist.paths_; } + + friend void from_json(const json &j, PathList &plist) { + j.get_to(plist.paths_); + } + +private: + std::unordered_set paths_; +}; + +/** + * @brief Stores path + path hash in a hashmap + * + */ +class PathInfoList { +private: + static constexpr const char *const kPath = "path"; + static constexpr const char *const kHash = "hash"; + +public: + PathInfoList() = default; + explicit PathInfoList( + std::initializer_list> + path_infos) { + for (const auto &pinfo : path_infos) { + Emplace(pinfo.first, pinfo.second); + } + } + + void Emplace(const std::string &pstr, const std::string &hash) { + auto path_str = Path::ToPathString(pstr); + path_infos_.emplace(std::move(path_str), hash); + } + + void ComputeHashForAll() { + for (auto &[path_str, hash] : path_infos_) { + hash = ComputeHash(path_str); + } + } + + const std::string &GetHash(const std::string &str) const { + auto path_str = Path::ToPathString(str); + const bool found = path_infos_.find(path_str) != path_infos_.end(); + env::assert_fatal(found, ""); + return path_infos_.at(path_str); + } + + bool IsEqual(const PathInfoList &other) const { + return path_infos_ == other.path_infos_; + } + + const std::unordered_map &GetPathInfos() const { + return path_infos_; + } + + std::unordered_set GetPaths() const { + std::unordered_set paths; + for (const auto &[path_str, hash] : path_infos_) { + paths.emplace(path_str); + } + return paths; + } + + // TODO, Add Compute Strategy enum + static std::string ComputeHash(const std::string &pstr) { + auto path_str = Path::ToPathString(pstr); + + // TODO, There might be a file checksum hash compute strategy + // This is the timestamp hash compute strategy + std::error_code errcode; + const std::uint64_t last_write_timestamp = + std::filesystem::last_write_time(path_str, errcode) + .time_since_epoch() + .count(); + env::assert_fatal(errcode.value() == 0, + fmt::format("{} not found", path_str)); + return std::to_string(last_write_timestamp); + } + + friend void to_json(json &j, const PathInfoList &plist) { + j = plist.path_infos_; + } + + friend void from_json(const json &j, PathInfoList &plist) { + j.get_to(plist.path_infos_); + } + +private: + std::unordered_map path_infos_; +}; + +// TODO, Remove this inline std::vector path_schema_convert(const std::vector &path_list, const std::function &cb = @@ -146,6 +298,7 @@ path_schema_convert(const std::vector &path_list, return internal_path_list; } +// TODO, Remove this inline path_unordered_set path_schema_convert(const fs_unordered_set &path_set, const std::function &cb = @@ -157,6 +310,7 @@ path_schema_convert(const fs_unordered_set &path_set, return internal_path_set; } +// TODO, Remove this inline fs_unordered_set path_schema_convert(const path_unordered_set &internal_path_set) { fs_unordered_set path_set; From 3f37a04ab9ff580585452513dfc72d122c5ba0b9 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 3 Dec 2022 03:34:09 -0800 Subject: [PATCH 34/35] [CI/CD] Update Github Actions to v3 --- .github/workflows/linux_gcc_cmake_build.yml | 8 ++++---- .github/workflows/msvc-analysis.yml | 4 ++-- .github/workflows/pages.yml | 2 +- .github/workflows/win_cmake_build.yml | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/linux_gcc_cmake_build.yml b/.github/workflows/linux_gcc_cmake_build.yml index a159ea7d..2f3de693 100644 --- a/.github/workflows/linux_gcc_cmake_build.yml +++ b/.github/workflows/linux_gcc_cmake_build.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true @@ -89,7 +89,7 @@ jobs: cpack -C Release -G ZIP - name: Upload CPack - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: "BuildExe_Linux" path: ${{github.workspace}}/${{env.BUILD_FOLDER_DEV_ALL}}/BuildCC-0.1.1-Linux.zip @@ -156,7 +156,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true @@ -298,7 +298,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true diff --git a/.github/workflows/msvc-analysis.yml b/.github/workflows/msvc-analysis.yml index bd370187..5590b87c 100644 --- a/.github/workflows/msvc-analysis.yml +++ b/.github/workflows/msvc-analysis.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: true @@ -61,7 +61,7 @@ jobs: # Upload SARIF file as an Artifact to download and view - name: Upload SARIF as an Artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: sarif-file path: ${{ steps.run-analysis.outputs.sarif }} diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 5d6eecae..59c8c35a 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -13,7 +13,7 @@ jobs: deploy: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true diff --git a/.github/workflows/win_cmake_build.yml b/.github/workflows/win_cmake_build.yml index 1d4a1098..3844fb97 100644 --- a/.github/workflows/win_cmake_build.yml +++ b/.github/workflows/win_cmake_build.yml @@ -24,7 +24,7 @@ jobs: runs-on: windows-2019 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true @@ -88,7 +88,7 @@ jobs: cpack -C Release -G ZIP - name: Upload CPack - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: "BuildExe_Win" path: ${{github.workspace}}/${{env.BUILD_FOLDER_MSVC_DEV_ALL}}/BuildCC-0.1.1-win64.zip @@ -162,7 +162,7 @@ jobs: runs-on: windows-2019 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: true From 27f44d5dd5fc0bcb1f5690ff1b36666868af8580 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 25 Dec 2022 15:14:53 -0800 Subject: [PATCH 35/35] Target schema updates (#231) --- buildcc/lib/target/CMakeLists.txt | 1 - .../lib/target/cmake/common_target_src.cmake | 2 - .../lib/target/include/target/api/deps_api.h | 12 +- .../target/include/target/api/include_api.h | 12 +- .../lib/target/include/target/api/lib_api.h | 10 +- .../lib/target/include/target/api/pch_api.h | 6 +- .../target/include/target/api/source_api.h | 6 +- .../lib/target/include/target/common/util.h | 13 +- .../custom_generator_context.h | 8 +- .../include/target/friend/compile_object.h | 17 +- .../target/interface/builder_interface.h | 117 -------- buildcc/lib/target/include/target/target.h | 12 +- .../lib/target/include/target/target_info.h | 14 +- buildcc/lib/target/mock/expect_target.h | 1 + .../lib/target/mock/target/recheck_states.cpp | 32 ++- buildcc/lib/target/src/api/lib_api.cpp | 2 +- buildcc/lib/target/src/api/sync_api.cpp | 41 ++- buildcc/lib/target/src/common/util.cpp | 46 ---- buildcc/lib/target/src/target/build.cpp | 13 +- .../src/target/friend/compile_object.cpp | 141 +++++----- .../target/src/target/friend/compile_pch.cpp | 49 ++-- .../target/src/target/friend/link_target.cpp | 46 ++-- .../lib/target/src/target/recheck_states.cpp | 1 + buildcc/lib/target/src/target/target.cpp | 28 -- buildcc/lib/target/src/target/tasks.cpp | 33 +-- buildcc/lib/target/test/path/CMakeLists.txt | 23 -- buildcc/lib/target/test/path/constants.h.in | 4 - buildcc/lib/target/test/path/path_main.cpp | 6 - buildcc/lib/target/test/path/test_path.cpp | 96 ------- buildcc/lib/target/test/target/CMakeLists.txt | 6 - .../test/target/test_builder_interface.cpp | 131 --------- .../test/target/test_custom_generator.cpp | 2 +- .../test/target/test_target_external_lib.cpp | 4 +- .../target/test/target/test_target_flags.cpp | 121 ++++++--- .../test/target/test_target_include_dir.cpp | 85 +++--- .../test/target/test_target_lib_dep.cpp | 4 +- .../target/test/target/test_target_pch.cpp | 244 +++++++++++++++-- .../target/test/target/test_target_source.cpp | 28 +- .../include/toolchain/api/flag_api.h | 34 +-- .../include/toolchain/api/toolchain_find.h | 9 +- .../toolchain/include/toolchain/toolchain.h | 16 +- .../lib/toolchain/src/api/toolchain_find.cpp | 7 +- .../toolchain/test/test_toolchain_find.cpp | 16 +- .../toolchain/test/test_toolchain_verify.cpp | 11 +- buildcc/schema/cmake/schema.cmake | 8 + buildcc/schema/include/schema/path.h | 253 ++++++------------ buildcc/schema/include/schema/target_schema.h | 58 ++-- .../include/schema/target_serialization.h | 2 +- buildcc/schema/src/target_serialization.cpp | 12 +- buildcc/schema/test/test_path_schema.cpp | 147 ++++++++++ .../test/test_toolchain_specialized.cpp | 12 +- 51 files changed, 940 insertions(+), 1062 deletions(-) delete mode 100644 buildcc/lib/target/src/common/util.cpp delete mode 100644 buildcc/lib/target/test/path/CMakeLists.txt delete mode 100644 buildcc/lib/target/test/path/constants.h.in delete mode 100644 buildcc/lib/target/test/path/path_main.cpp delete mode 100644 buildcc/lib/target/test/path/test_path.cpp delete mode 100644 buildcc/lib/target/test/target/test_builder_interface.cpp create mode 100644 buildcc/schema/test/test_path_schema.cpp diff --git a/buildcc/lib/target/CMakeLists.txt b/buildcc/lib/target/CMakeLists.txt index a1cf05c2..e530fde4 100644 --- a/buildcc/lib/target/CMakeLists.txt +++ b/buildcc/lib/target/CMakeLists.txt @@ -4,7 +4,6 @@ include(cmake/common_target_src.cmake) if (${TESTING}) set(TARGET_DIR "${CMAKE_CURRENT_SOURCE_DIR}") include(cmake/mock_target.cmake) - add_subdirectory(test/path) add_subdirectory(test/target) endif() diff --git a/buildcc/lib/target/cmake/common_target_src.cmake b/buildcc/lib/target/cmake/common_target_src.cmake index 92822197..69558576 100644 --- a/buildcc/lib/target/cmake/common_target_src.cmake +++ b/buildcc/lib/target/cmake/common_target_src.cmake @@ -8,8 +8,6 @@ set(COMMON_TARGET_SRCS include/target/common/target_config.h include/target/common/target_state.h include/target/common/target_env.h - - src/common/util.cpp include/target/common/util.h # API diff --git a/buildcc/lib/target/include/target/api/deps_api.h b/buildcc/lib/target/include/target/api/deps_api.h index 3fecdf2a..dfb5bb99 100644 --- a/buildcc/lib/target/include/target/api/deps_api.h +++ b/buildcc/lib/target/include/target/api/deps_api.h @@ -35,14 +35,14 @@ template class DepsApi { // TODO, Rename AddObjectDependency // TODO, Rename AddTargetDependency - const fs_unordered_set &GetCompileDependencies() const { + std::vector GetCompileDependencies() const { const auto &t = static_cast(*this); - return t.user_.compile_dependencies; + return t.user_.compile_dependencies.GetPaths(); } - const fs_unordered_set &GetLinkDependencies() const { + std::vector GetLinkDependencies() const { const auto &t = static_cast(*this); - return t.user_.link_dependencies; + return t.user_.link_dependencies.GetPaths(); } /** @@ -52,7 +52,7 @@ template class DepsApi { void AddCompileDependencyAbsolute(const fs::path &absolute_path) { auto &t = static_cast(*this); - t.user_.compile_dependencies.insert(absolute_path); + t.user_.compile_dependencies.Emplace(absolute_path, ""); } /** @@ -73,7 +73,7 @@ template class DepsApi { void AddLinkDependencyAbsolute(const fs::path &absolute_path) { auto &t = static_cast(*this); - t.user_.link_dependencies.insert(absolute_path); + t.user_.link_dependencies.Emplace(absolute_path, ""); } /** diff --git a/buildcc/lib/target/include/target/api/include_api.h b/buildcc/lib/target/include/target/api/include_api.h index 159594d8..d6702dc1 100644 --- a/buildcc/lib/target/include/target/api/include_api.h +++ b/buildcc/lib/target/include/target/api/include_api.h @@ -32,21 +32,21 @@ namespace buildcc::internal { // TargetEnv template class IncludeApi { public: - const fs_unordered_set &GetHeaderFiles() const { + std::vector GetHeaderFiles() const { const auto &t = static_cast(*this); - return t.user_.headers; + return t.user_.headers.GetPaths(); } - const fs_unordered_set &GetIncludeDirs() const { + const std::vector &GetIncludeDirs() const { const auto &t = static_cast(*this); - return t.user_.include_dirs; + return t.user_.include_dirs.GetPaths(); } void AddHeaderAbsolute(const fs::path &absolute_filepath) { auto &t = static_cast(*this); t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); - t.user_.headers.insert(absolute_filepath); + t.user_.headers.Emplace(absolute_filepath, ""); } void GlobHeadersAbsolute(const fs::path &absolute_path) { @@ -63,7 +63,7 @@ template class IncludeApi { bool glob_headers = false) { auto &t = static_cast(*this); - t.user_.include_dirs.insert(absolute_include_dir); + t.user_.include_dirs.Emplace(absolute_include_dir); if (glob_headers) { GlobHeadersAbsolute(absolute_include_dir); diff --git a/buildcc/lib/target/include/target/api/lib_api.h b/buildcc/lib/target/include/target/api/lib_api.h index e6fe0bf1..5506bdf1 100644 --- a/buildcc/lib/target/include/target/api/lib_api.h +++ b/buildcc/lib/target/include/target/api/lib_api.h @@ -41,9 +41,9 @@ namespace buildcc::internal { // Target::GetTargetPath template class LibApi { public: - const std::vector &GetLibDeps() const { + std::vector GetLibDeps() const { const auto &t = static_cast(*this); - return t.user_.libs; + return t.user_.libs.GetPaths(); } const std::vector &GetExternalLibDeps() const { @@ -51,14 +51,14 @@ template class LibApi { return t.user_.external_libs; } - const fs_unordered_set &GetLibDirs() const { + const std::vector &GetLibDirs() const { const auto &t = static_cast(*this); - return t.user_.lib_dirs; + return t.user_.lib_dirs.GetPaths(); } void AddLibDirAbsolute(const fs::path &absolute_lib_dir) { auto &t = static_cast(*this); - t.user_.lib_dirs.insert(absolute_lib_dir); + t.user_.lib_dirs.Emplace(absolute_lib_dir); } void AddLibDir(const fs::path &relative_lib_dir) { diff --git a/buildcc/lib/target/include/target/api/pch_api.h b/buildcc/lib/target/include/target/api/pch_api.h index 7dfdd34e..dec92f8d 100644 --- a/buildcc/lib/target/include/target/api/pch_api.h +++ b/buildcc/lib/target/include/target/api/pch_api.h @@ -31,9 +31,9 @@ namespace buildcc::internal { // TargetEnv template class PchApi { public: - const fs_unordered_set &GetPchFiles() const { + std::vector GetPchFiles() const { const auto &t = static_cast(*this); - return t.user_.pchs; + return t.user_.pchs.GetPaths(); } void AddPchAbsolute(const fs::path &absolute_filepath) { @@ -42,7 +42,7 @@ template class PchApi { t.toolchain_.GetConfig().ExpectsValidHeader(absolute_filepath); const fs::path absolute_pch = fs::path(absolute_filepath).make_preferred(); - t.user_.pchs.insert(absolute_pch); + t.user_.pchs.Emplace(absolute_pch, ""); } void AddPch(const fs::path &relative_filename, diff --git a/buildcc/lib/target/include/target/api/source_api.h b/buildcc/lib/target/include/target/api/source_api.h index 7ff7eee6..d3674158 100644 --- a/buildcc/lib/target/include/target/api/source_api.h +++ b/buildcc/lib/target/include/target/api/source_api.h @@ -31,16 +31,16 @@ namespace buildcc::internal { // TargetEnv template class SourceApi { public: - const fs_unordered_set &GetSourceFiles() const { + std::vector GetSourceFiles() const { const auto &t = static_cast(*this); - return t.user_.sources; + return t.user_.sources.GetPaths(); } void AddSourceAbsolute(const fs::path &absolute_source) { auto &t = static_cast(*this); t.toolchain_.GetConfig().ExpectsValidSource(absolute_source); - t.user_.sources.emplace(fs::path(absolute_source).make_preferred()); + t.user_.sources.Emplace(absolute_source, ""); } void GlobSourcesAbsolute(const fs::path &absolute_source_dir) { diff --git a/buildcc/lib/target/include/target/common/util.h b/buildcc/lib/target/include/target/common/util.h index 683216ad..30191e89 100644 --- a/buildcc/lib/target/include/target/common/util.h +++ b/buildcc/lib/target/include/target/common/util.h @@ -29,10 +29,15 @@ template std::string aggregate(const T &list) { return fmt::format("{}", fmt::join(list, " ")); } -std::string aggregate(const buildcc::fs_unordered_set &paths); - -std::string aggregate_with_prefix(const std::string &prefix, - const fs_unordered_set &dirs); +template +std::string aggregate_with_prefix(const std::string &prefix, const T &list) { + std::vector agg_list; + for (const auto &l : list) { + auto formatted_output = fmt::format("{}{}", prefix, l); + agg_list.emplace_back(std::move(formatted_output)); + } + return aggregate(agg_list); +} } // namespace buildcc::internal diff --git a/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h b/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h index 4c49d5ff..53bd59a6 100644 --- a/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h +++ b/buildcc/lib/target/include/target/custom_generator/custom_generator_context.h @@ -26,14 +26,14 @@ namespace buildcc { class CustomGeneratorContext { public: CustomGeneratorContext(const env::Command &c, - const std::unordered_set &i, - const std::unordered_set &o, + const std::vector &i, + const std::vector &o, const std::vector &ub) : command(c), inputs(i), outputs(o), userblob(ub) {} const env::Command &command; - const std::unordered_set &inputs; - const std::unordered_set &outputs; + const std::vector &inputs; + const std::vector &outputs; const std::vector &userblob; }; diff --git a/buildcc/lib/target/include/target/friend/compile_object.h b/buildcc/lib/target/include/target/friend/compile_object.h index 1cbfbc9f..3e2e8ec8 100644 --- a/buildcc/lib/target/include/target/friend/compile_object.h +++ b/buildcc/lib/target/include/target/friend/compile_object.h @@ -54,29 +54,28 @@ class CompileObject { void Task(); const ObjectData &GetObjectData(const fs::path &absolute_source) const; - const std::unordered_map & - GetObjectDataMap() const { + const std::unordered_map &GetObjectDataMap() const { return object_files_; } - fs_unordered_set GetCompiledSources() const; + std::vector GetCompiledSources() const; tf::Task &GetTask() { return compile_task_; } private: fs::path ConstructObjectPath(const fs::path &absolute_source_file) const; - void BuildObjectCompile(std::vector &source_files, - std::vector &dummy_source_files); + void BuildObjectCompile(std::vector &source_files, + std::vector &dummy_source_files); void PreObjectCompile(); - void CompileSources(std::vector &source_files); - void RecompileSources(std::vector &source_files, - std::vector &dummy_source_files); + void CompileSources(std::vector &source_files); + void RecompileSources(std::vector &source_files, + std::vector &dummy_source_files); private: Target &target_; - std::unordered_map object_files_; + std::unordered_map object_files_; tf::Task compile_task_; }; diff --git a/buildcc/lib/target/include/target/interface/builder_interface.h b/buildcc/lib/target/include/target/interface/builder_interface.h index 40184f6f..c020fd91 100644 --- a/buildcc/lib/target/include/target/interface/builder_interface.h +++ b/buildcc/lib/target/include/target/interface/builder_interface.h @@ -29,71 +29,6 @@ namespace buildcc::internal { -enum class PathState { - kNoChange, - kRemoved, - kAdded, - kUpdated, -}; - -template -inline bool CheckChanged(const T &previous, const T ¤t) { - bool changed = false; - if (previous != current) { - changed = true; - } - return changed; -} - -/** - * @brief - * - * @return PathState Returns first state found if `Removed`, `Added` or - * `Updated` - * If none of the above states are true then it returns `NoChange` - */ -inline PathState CheckPaths(const internal::path_unordered_set &previous_path, - const internal::path_unordered_set ¤t_path) { - PathState state{PathState::kNoChange}; - - // * Old path is removed - const bool removed = std::any_of( - previous_path.begin(), previous_path.end(), [&](const internal::Path &p) { - return current_path.find(p) == current_path.end(); - }); - if (removed) { - state = PathState::kRemoved; - } else { - (void)std::any_of(current_path.cbegin(), current_path.cend(), - [&](const internal::Path &p) -> bool { - bool dirty = false; - const auto find = previous_path.find(p); - const bool added_cond = (find == previous_path.end()); - if (added_cond) { - dirty = true; - state = PathState::kAdded; - } else { - const bool updated_cond = - (p.last_write_timestamp > - find->last_write_timestamp); - if (updated_cond) { - dirty = true; - state = PathState::kUpdated; - } else { - dirty = false; - } - } - return dirty; - }); - } - return state; -} - -// TODO, 1. Consider updating Recheck* APIs - do not modify internal `dirty_` -// flag -// TODO, 2. Consider removing dependency on target/common/util.h -// TODO, 3. Consider making Recheck* APIs free namespaced functions instead of -// only within the scope of BuilderInterfaces (See TODO 1. and 2. first) class BuilderInterface { public: @@ -102,58 +37,6 @@ class BuilderInterface { const std::string &GetUniqueId() const { return unique_id_; } tf::Taskflow &GetTaskflow() { return tf_; } -protected: - template - void RecheckChanged( - const T &previous, const T ¤t, - const std::function &callback = []() {}) { - ASSERT_FATAL(callback, "Bad function: callback"); - - if (dirty_) { - return; - } - - if (CheckChanged(previous, current)) { - callback(); - dirty_ = true; - } - } - - void RecheckPaths( - const internal::path_unordered_set &previous_path, - const internal::path_unordered_set ¤t_path, - const std::function &path_removed_cb = []() {}, - const std::function &path_added_cb = []() {}, - const std::function &path_updated_cb = []() {}) { - ASSERT_FATAL(path_removed_cb, "Bad function: path_removed_cb"); - ASSERT_FATAL(path_added_cb, "Bad function: path_added_cb"); - ASSERT_FATAL(path_updated_cb, "Bad function: path_updated_cb"); - - if (dirty_) { - return; - } - - auto path_state = CheckPaths(previous_path, current_path); - switch (path_state) { - case PathState::kRemoved: - path_removed_cb(); - dirty_ = true; - break; - case PathState::kAdded: - path_added_cb(); - dirty_ = true; - break; - case PathState::kUpdated: - path_updated_cb(); - dirty_ = true; - break; - case PathState::kNoChange: - default: - dirty_ = false; - break; - } - } - protected: bool dirty_{false}; std::string unique_id_; diff --git a/buildcc/lib/target/include/target/target.h b/buildcc/lib/target/include/target/target.h index 816c5b2d..1e0ab020 100644 --- a/buildcc/lib/target/include/target/target.h +++ b/buildcc/lib/target/include/target/target.h @@ -96,17 +96,6 @@ class Target : public internal::BuilderInterface, env::optional SelectCompileFlags(FileExt ext) const; env::optional SelectCompiler(FileExt ext) const; - // Recompilation checks - void RecheckPaths(const internal::path_unordered_set &previous_path, - const internal::path_unordered_set ¤t_path); - void RecheckDirs(const fs_unordered_set &previous_dirs, - const fs_unordered_set ¤t_dirs); - void RecheckFlags(const std::unordered_set &previous_flags, - const std::unordered_set ¤t_flags); - void - RecheckExternalLib(const std::vector &previous_external_libs, - const std::vector ¤t_external_libs); - // Tasks void EndTask(); void TaskDeps(); @@ -119,6 +108,7 @@ class Target : public internal::BuilderInterface, void PathAdded(); void PathUpdated(); + void PathChanged(); void DirChanged(); void FlagChanged(); void ExternalLibChanged(); diff --git a/buildcc/lib/target/include/target/target_info.h b/buildcc/lib/target/include/target/target_info.h index 10b1c5c9..b8758ce4 100644 --- a/buildcc/lib/target/include/target/target_info.h +++ b/buildcc/lib/target/include/target/target_info.h @@ -34,18 +34,6 @@ namespace buildcc { -// TODO, Make this private -struct UserTargetSchema : public internal::TargetSchema { - fs_unordered_set sources; - fs_unordered_set headers; - fs_unordered_set pchs; - - std::vector libs; - - fs_unordered_set compile_dependencies; - fs_unordered_set link_dependencies; -}; - // NOTE: BaseTarget info is meant to hold information that is common to // multiple targets // It is also meant to be used in situations where we do not need to build @@ -78,7 +66,7 @@ class TargetInfo : public internal::SourceApi, const BaseToolchain &toolchain_; TargetEnv env_; - UserTargetSchema user_; + internal::TargetSchema user_; private: void Initialize(); diff --git a/buildcc/lib/target/mock/expect_target.h b/buildcc/lib/target/mock/expect_target.h index 8b398371..816e3175 100644 --- a/buildcc/lib/target/mock/expect_target.h +++ b/buildcc/lib/target/mock/expect_target.h @@ -19,6 +19,7 @@ void TargetExpect_PathRemoved(unsigned int calls, Target *target); void TargetExpect_PathAdded(unsigned int calls, Target *target); void TargetExpect_PathUpdated(unsigned int calls, Target *target); +void TargetExpect_PathChanged(unsigned int calls, Target *target); void TargetExpect_DirChanged(unsigned int calls, Target *target); void TargetExpect_FlagChanged(unsigned int calls, Target *target); void TargetExpect_ExternalLibChanged(unsigned int calls, Target *target); diff --git a/buildcc/lib/target/mock/target/recheck_states.cpp b/buildcc/lib/target/mock/target/recheck_states.cpp index 40586006..f7ff1f34 100644 --- a/buildcc/lib/target/mock/target/recheck_states.cpp +++ b/buildcc/lib/target/mock/target/recheck_states.cpp @@ -13,12 +13,8 @@ static constexpr const char *const SOURCE_ADDED_FUNCTION = static constexpr const char *const SOURCE_UPDATED_FUNCTION = "Target::SourceUpdated"; -static constexpr const char *const PATH_REMOVED_FUNCTION = - "Target::PathRemoved"; -static constexpr const char *const PATH_ADDED_FUNCTION = "Target::PathAdded"; -static constexpr const char *const PATH_UPDATED_FUNCTION = - "Target::PathUpdated"; - +static constexpr const char *const PATH_CHANGED_FUNCTION = + "Target::PathChanged"; static constexpr const char *const DIR_CHANGED_FUNCTION = "Target::DirChanged"; static constexpr const char *const FLAG_CHANGED_FUNCTION = "Target::FlagChanged"; @@ -37,14 +33,12 @@ void Target::SourceUpdated() { } // Path rechecks -void Target::PathRemoved() { - mock().actualCall(PATH_REMOVED_FUNCTION).onObject(this); -} -void Target::PathAdded() { - mock().actualCall(PATH_ADDED_FUNCTION).onObject(this); -} -void Target::PathUpdated() { - mock().actualCall(PATH_UPDATED_FUNCTION).onObject(this); +void Target::PathRemoved() { PathChanged(); } +void Target::PathAdded() { PathChanged(); } +void Target::PathUpdated() { PathChanged(); } + +void Target::PathChanged() { + mock().actualCall(PATH_CHANGED_FUNCTION).onObject(this); } void Target::DirChanged() { @@ -72,13 +66,17 @@ void TargetExpect_SourceUpdated(unsigned int calls, Target *target) { } void TargetExpect_PathRemoved(unsigned int calls, Target *target) { - mock().expectNCalls(calls, PATH_REMOVED_FUNCTION).onObject(target); + TargetExpect_PathChanged(calls, target); } void TargetExpect_PathAdded(unsigned int calls, Target *target) { - mock().expectNCalls(calls, PATH_ADDED_FUNCTION).onObject(target); + TargetExpect_PathChanged(calls, target); } void TargetExpect_PathUpdated(unsigned int calls, Target *target) { - mock().expectNCalls(calls, PATH_UPDATED_FUNCTION).onObject(target); + TargetExpect_PathChanged(calls, target); +} + +void TargetExpect_PathChanged(unsigned int calls, Target *target) { + mock().expectNCalls(calls, PATH_CHANGED_FUNCTION).onObject(target); } void TargetExpect_DirChanged(unsigned int calls, Target *target) { diff --git a/buildcc/lib/target/src/api/lib_api.cpp b/buildcc/lib/target/src/api/lib_api.cpp index 156e3dd8..0d24ca8c 100644 --- a/buildcc/lib/target/src/api/lib_api.cpp +++ b/buildcc/lib/target/src/api/lib_api.cpp @@ -24,7 +24,7 @@ namespace buildcc::internal { template void LibApi::AddLibDep(const BaseTarget &lib_dep) { T &t = static_cast(*this); - t.user_.libs.push_back(lib_dep.GetTargetPath()); + t.user_.libs.Emplace(lib_dep.GetTargetPath(), ""); } template class LibApi; diff --git a/buildcc/lib/target/src/api/sync_api.cpp b/buildcc/lib/target/src/api/sync_api.cpp index c10073f4..7cecfc06 100644 --- a/buildcc/lib/target/src/api/sync_api.cpp +++ b/buildcc/lib/target/src/api/sync_api.cpp @@ -125,82 +125,77 @@ void SyncApi::SpecializedInsert(TargetType target, switch (o) { case SyncOption::PreprocessorFlags: t.user_.preprocessor_flags.insert( + t.user_.preprocessor_flags.end(), std::make_move_iterator(target.user_.preprocessor_flags.begin()), std::make_move_iterator(target.user_.preprocessor_flags.end())); break; case SyncOption::CommonCompileFlags: t.user_.common_compile_flags.insert( + t.user_.common_compile_flags.end(), std::make_move_iterator(target.user_.common_compile_flags.begin()), std::make_move_iterator(target.user_.common_compile_flags.end())); break; case SyncOption::PchCompileFlags: t.user_.pch_compile_flags.insert( + t.user_.pch_compile_flags.end(), std::make_move_iterator(target.user_.pch_compile_flags.begin()), std::make_move_iterator(target.user_.pch_compile_flags.end())); break; case SyncOption::PchObjectFlags: t.user_.pch_object_flags.insert( + t.user_.pch_object_flags.end(), std::make_move_iterator(target.user_.pch_object_flags.begin()), std::make_move_iterator(target.user_.pch_object_flags.end())); break; case SyncOption::AsmCompileFlags: t.user_.asm_compile_flags.insert( + t.user_.asm_compile_flags.end(), std::make_move_iterator(target.user_.asm_compile_flags.begin()), std::make_move_iterator(target.user_.asm_compile_flags.end())); break; case SyncOption::CCompileFlags: t.user_.c_compile_flags.insert( + t.user_.c_compile_flags.end(), std::make_move_iterator(target.user_.c_compile_flags.begin()), std::make_move_iterator(target.user_.c_compile_flags.end())); break; case SyncOption::CppCompileFlags: t.user_.cpp_compile_flags.insert( + t.user_.cpp_compile_flags.end(), std::make_move_iterator(target.user_.cpp_compile_flags.begin()), std::make_move_iterator(target.user_.cpp_compile_flags.end())); break; case SyncOption::LinkFlags: t.user_.link_flags.insert( + t.user_.link_flags.end(), std::make_move_iterator(target.user_.link_flags.begin()), std::make_move_iterator(target.user_.link_flags.end())); break; case SyncOption::CompileDependencies: - t.user_.compile_dependencies.insert( - std::make_move_iterator(target.user_.compile_dependencies.begin()), - std::make_move_iterator(target.user_.compile_dependencies.end())); + t.user_.compile_dependencies.Insert( + std::move(target.user_.compile_dependencies)); break; case SyncOption::LinkDependencies: - t.user_.link_dependencies.insert( - std::make_move_iterator(target.user_.link_dependencies.begin()), - std::make_move_iterator(target.user_.link_dependencies.end())); + t.user_.link_dependencies.Insert( + std::move(target.user_.link_dependencies)); break; case SyncOption::SourceFiles: - t.user_.sources.insert( - std::make_move_iterator(target.user_.sources.begin()), - std::make_move_iterator(target.user_.sources.end())); + t.user_.sources.Insert(std::move(target.user_.sources)); break; case SyncOption::HeaderFiles: - t.user_.headers.insert( - std::make_move_iterator(target.user_.headers.begin()), - std::make_move_iterator(target.user_.headers.end())); + t.user_.headers.Insert(std::move(target.user_.headers)); break; case SyncOption::PchFiles: - t.user_.pchs.insert(std::make_move_iterator(target.user_.pchs.begin()), - std::make_move_iterator(target.user_.pchs.end())); + t.user_.pchs.Insert(std::move(target.user_.pchs)); break; case SyncOption::LibDeps: - t.user_.libs.insert(t.user_.libs.end(), - std::make_move_iterator(target.user_.libs.begin()), - std::make_move_iterator(target.user_.libs.end())); + t.user_.libs.Insert(std::move(target.user_.libs)); break; case SyncOption::IncludeDirs: - t.user_.include_dirs.insert( - std::make_move_iterator(target.user_.include_dirs.begin()), - std::make_move_iterator(target.user_.include_dirs.end())); + t.user_.include_dirs.Insert(std::move(target.user_.include_dirs)); break; case SyncOption::LibDirs: - t.user_.lib_dirs.insert( - std::make_move_iterator(target.user_.lib_dirs.begin()), - std::make_move_iterator(target.user_.lib_dirs.end())); + t.user_.lib_dirs.Insert(std::move(target.user_.lib_dirs)); break; case SyncOption::ExternalLibDeps: t.user_.external_libs.insert( diff --git a/buildcc/lib/target/src/common/util.cpp b/buildcc/lib/target/src/common/util.cpp deleted file mode 100644 index 881e610a..00000000 --- a/buildcc/lib/target/src/common/util.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2021-2022 Niket Naidu. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "target/common/util.h" - -#include "env/assert_fatal.h" -#include "env/env.h" - -#include "fmt/format.h" - -namespace buildcc::internal { - -// Aggregates - -std::string aggregate(const buildcc::fs_unordered_set &paths) { - std::vector agg; - std::transform( - paths.begin(), paths.end(), std::back_inserter(agg), - [](const fs::path &p) -> std::string { return fmt::format("{}", p); }); - return aggregate(agg); -} - -std::string aggregate_with_prefix(const std::string &prefix, - const fs_unordered_set &dirs) { - std::vector agg; - std::transform(dirs.begin(), dirs.end(), std::back_inserter(agg), - [&](const fs::path &dir) -> std::string { - return fmt::format("{}{}", prefix, fmt::format("{}", dir)); - }); - return aggregate(agg); -} - -} // namespace buildcc::internal diff --git a/buildcc/lib/target/src/target/build.cpp b/buildcc/lib/target/src/target/build.cpp index a6996684..18ae8fa4 100644 --- a/buildcc/lib/target/src/target/build.cpp +++ b/buildcc/lib/target/src/target/build.cpp @@ -55,28 +55,27 @@ void Target::Build() { env::log_trace(name_, __FUNCTION__); // PCH state - if (!user_.pchs.empty()) { + if (!user_.pchs.GetPathInfos().empty()) { state_.PchDetected(); } // Source - Object relation // Source state - for (const auto &abs_source : user_.sources) { + for (const auto &source_info : user_.sources.GetPathInfos()) { // Set state - state_.SourceDetected(toolchain_.GetConfig().GetFileExt(abs_source)); + state_.SourceDetected(toolchain_.GetConfig().GetFileExt(source_info.path)); // Relate input source with output object - compile_object_.AddObjectData(abs_source); + compile_object_.AddObjectData(source_info.path); } // Target default arguments command_.AddDefaultArguments({ {kIncludeDirs, - internal::aggregate_with_prefix( + internal::aggregate_with_prefix>( toolchain_.GetConfig().prefix_include_dir, GetIncludeDirs())}, - {kLibDirs, internal::aggregate_with_prefix( + {kLibDirs, internal::aggregate_with_prefix>( toolchain_.GetConfig().prefix_lib_dir, GetLibDirs())}, - {kPreprocessorFlags, internal::aggregate(GetPreprocessorFlags())}, {kCommonCompileFlags, internal::aggregate(GetCommonCompileFlags())}, // TODO, Cache more flags here diff --git a/buildcc/lib/target/src/target/friend/compile_object.cpp b/buildcc/lib/target/src/target/friend/compile_object.cpp index a20c36d8..f905426f 100644 --- a/buildcc/lib/target/src/target/friend/compile_object.cpp +++ b/buildcc/lib/target/src/target/friend/compile_object.cpp @@ -34,13 +34,13 @@ void CompileObject::AddObjectData(const fs::path &absolute_source_path) { ConstructObjectPath(absolute_source_path); fs::create_directories(absolute_object_path.parent_path()); - object_files_.emplace(absolute_source_path, - ObjectData(absolute_object_path, "")); + object_files_.try_emplace( + internal::PathInfo::ToPathString(absolute_source_path), + absolute_object_path, ""); } void CompileObject::CacheCompileCommands() { - for (auto &object_iter : object_files_) { - const fs::path &absolute_current_source = object_iter.first; + for (auto &[absolute_current_source, object_data] : object_files_) { const std::string output = fmt::format("{}", GetObjectData(absolute_current_source).output); @@ -52,7 +52,7 @@ void CompileObject::CacheCompileCommands() { target_.SelectCompileFlags(type).value_or(""); const std::string selected_compiler = fmt::format("{}", fs::path(target_.SelectCompiler(type).value_or(""))); - object_iter.second.command = target_.command_.Construct( + object_data.command = target_.command_.Construct( target_.GetConfig().compile_command, { {kCompiler, selected_compiler}, @@ -63,20 +63,22 @@ void CompileObject::CacheCompileCommands() { } } -fs_unordered_set CompileObject::GetCompiledSources() const { - fs_unordered_set compiled_sources; - for (const auto &p : object_files_) { - compiled_sources.insert(p.second.output); +std::vector CompileObject::GetCompiledSources() const { + std::vector compiled_sources; + for (const auto &[_, object_data] : object_files_) { + compiled_sources.push_back(object_data.output); } return compiled_sources; } const CompileObject::ObjectData & CompileObject::GetObjectData(const fs::path &absolute_source) const { - const auto fiter = object_files_.find(absolute_source); + const auto sanitized_source = + internal::PathInfo::ToPathString(absolute_source); + const auto fiter = object_files_.find(sanitized_source); env::assert_fatal(fiter != object_files_.end(), fmt::format("{} not found", absolute_source)); - return object_files_.at(absolute_source); + return object_files_.at(sanitized_source); } // PRIVATE @@ -162,8 +164,8 @@ CompileObject::ConstructObjectPath(const fs::path &absolute_source_file) const { } void CompileObject::BuildObjectCompile( - std::vector &source_files, - std::vector &dummy_source_files) { + std::vector &source_files, + std::vector &dummy_source_files) { PreObjectCompile(); const auto &serialization = target_.serialization_; @@ -173,24 +175,33 @@ void CompileObject::BuildObjectCompile( if (!serialization.IsLoaded()) { target_.dirty_ = true; } else { - target_.RecheckFlags(load_target_schema.preprocessor_flags, - user_target_schema.preprocessor_flags); - target_.RecheckFlags(load_target_schema.common_compile_flags, - user_target_schema.common_compile_flags); - target_.RecheckFlags(load_target_schema.pch_object_flags, - user_target_schema.pch_object_flags); - target_.RecheckFlags(load_target_schema.asm_compile_flags, - user_target_schema.asm_compile_flags); - target_.RecheckFlags(load_target_schema.c_compile_flags, - user_target_schema.c_compile_flags); - target_.RecheckFlags(load_target_schema.cpp_compile_flags, - user_target_schema.cpp_compile_flags); - target_.RecheckDirs(load_target_schema.include_dirs, - user_target_schema.include_dirs); - target_.RecheckPaths(load_target_schema.internal_headers, - user_target_schema.internal_headers); - target_.RecheckPaths(load_target_schema.internal_compile_dependencies, - user_target_schema.internal_compile_dependencies); + if (target_.dirty_) { + } else if (!(load_target_schema.preprocessor_flags == + user_target_schema.preprocessor_flags) || + !(load_target_schema.common_compile_flags == + user_target_schema.common_compile_flags) || + !(load_target_schema.pch_object_flags == + user_target_schema.pch_object_flags) || + !(load_target_schema.asm_compile_flags == + user_target_schema.asm_compile_flags) || + !(load_target_schema.c_compile_flags == + user_target_schema.c_compile_flags) || + !(load_target_schema.cpp_compile_flags == + user_target_schema.cpp_compile_flags)) { + target_.dirty_ = true; + target_.FlagChanged(); + } else if (!(load_target_schema.include_dirs == + user_target_schema.include_dirs)) { + target_.dirty_ = true; + target_.DirChanged(); + } else if (!(load_target_schema.headers == user_target_schema.headers)) { + target_.dirty_ = true; + target_.PathChanged(); + } else if (!(load_target_schema.compile_dependencies == + user_target_schema.compile_dependencies)) { + target_.dirty_ = true; + target_.PathChanged(); + } } if (target_.dirty_) { @@ -204,67 +215,55 @@ void CompileObject::PreObjectCompile() { auto &target_user_schema = target_.user_; // Convert user_source_files to current_source_files - target_user_schema.internal_sources = - internal::path_schema_convert(target_user_schema.sources); + target_user_schema.sources.ComputeHashForAll(); // Convert user_header_files to current_header_files - target_user_schema.internal_headers = - internal::path_schema_convert(target_user_schema.headers); + target_user_schema.headers.ComputeHashForAll(); // Convert user_compile_dependencies to current_compile_dependencies - target_user_schema.internal_compile_dependencies = - internal::path_schema_convert(target_user_schema.compile_dependencies); + target_user_schema.compile_dependencies.ComputeHashForAll(); } -void CompileObject::CompileSources(std::vector &source_files) { +void CompileObject::CompileSources( + std::vector &source_files) { const auto &target_user_schema = target_.user_; - source_files = - std::vector(target_user_schema.internal_sources.begin(), - target_user_schema.internal_sources.end()); + target_user_schema.sources.GetPathInfos(); + source_files = target_user_schema.sources.GetPathInfos(); } void CompileObject::RecompileSources( - std::vector &source_files, - std::vector &dummy_source_files) { + std::vector &source_files, + std::vector &dummy_source_files) { const auto &serialization = target_.serialization_; const auto &user_target_schema = target_.user_; - const auto &previous_source_files = serialization.GetLoad().internal_sources; - - // * Cannot find previous source in current source files - const bool is_source_removed = - std::any_of(previous_source_files.begin(), previous_source_files.end(), - [&](const internal::Path &p) { - return user_target_schema.internal_sources.find(p) == - user_target_schema.internal_sources.end(); - }); - - if (is_source_removed) { - target_.dirty_ = true; - target_.SourceRemoved(); - } - - for (const auto ¤t_file : user_target_schema.internal_sources) { - // Find current_file in the loaded sources - auto iter = previous_source_files.find(current_file); - - if (iter == previous_source_files.end()) { - // *1 New source file added to build - source_files.push_back(current_file); + auto previous_source_files = + serialization.GetLoad().sources.GetUnorderedPathInfos(); + + for (const auto ¤t_path_info : + user_target_schema.sources.GetPathInfos()) { + const auto ¤t_path = current_path_info.path; + if (previous_source_files.count(current_path) == 0) { + // Added + source_files.push_back(current_path_info); target_.dirty_ = true; target_.SourceAdded(); } else { - // *2 Current file is updated - if (current_file.last_write_timestamp > iter->last_write_timestamp) { - source_files.push_back(current_file); + if (!(previous_source_files.at(current_path) == current_path_info.hash)) { + // Updated + source_files.push_back(current_path_info); target_.dirty_ = true; target_.SourceUpdated(); } else { - // ELSE - // *3 Do nothing - dummy_source_files.push_back(current_file); + dummy_source_files.push_back(current_path_info); } + previous_source_files.erase(current_path); } } + + if (!previous_source_files.empty()) { + target_.dirty_ = true; + target_.SourceRemoved(); + } } } // namespace buildcc::internal diff --git a/buildcc/lib/target/src/target/friend/compile_pch.cpp b/buildcc/lib/target/src/target/friend/compile_pch.cpp index 8af27578..be3b5141 100644 --- a/buildcc/lib/target/src/target/friend/compile_pch.cpp +++ b/buildcc/lib/target/src/target/friend/compile_pch.cpp @@ -40,7 +40,7 @@ constexpr const char *const kFormat = R"(// Generated by BuildCC )"; void AggregateToFile(const fs::path &filename, - const buildcc::fs_unordered_set &header_files) { + const std::vector &header_files) { std::string aggregated_includes; for (const auto &hf : header_files) { std::string temp = fmt::format("#include \"{}\"\r\n", hf); @@ -80,24 +80,29 @@ void CompilePch::BuildCompile() { if (!serialization.IsLoaded()) { target_.dirty_ = true; } else { - target_.RecheckFlags(load_target_schema.preprocessor_flags, - user_target_schema.preprocessor_flags); - target_.RecheckFlags(load_target_schema.common_compile_flags, - user_target_schema.common_compile_flags); - target_.RecheckFlags(load_target_schema.c_compile_flags, - user_target_schema.c_compile_flags); - target_.RecheckFlags(load_target_schema.cpp_compile_flags, - user_target_schema.cpp_compile_flags); - target_.RecheckDirs(load_target_schema.include_dirs, - user_target_schema.include_dirs); - target_.RecheckPaths(load_target_schema.internal_headers, - user_target_schema.internal_headers); - - target_.RecheckFlags(load_target_schema.pch_compile_flags, - user_target_schema.pch_compile_flags); - target_.RecheckPaths(load_target_schema.internal_pchs, - user_target_schema.internal_pchs); - if (!load_target_schema.pch_compiled) { + if (!(load_target_schema.preprocessor_flags == + user_target_schema.preprocessor_flags) || + !(load_target_schema.common_compile_flags == + user_target_schema.common_compile_flags) || + !(load_target_schema.pch_compile_flags == + user_target_schema.pch_compile_flags) || + !(load_target_schema.c_compile_flags == + user_target_schema.c_compile_flags) || + !(load_target_schema.cpp_compile_flags == + user_target_schema.cpp_compile_flags)) { + target_.dirty_ = true; + target_.FlagChanged(); + } else if (!(load_target_schema.include_dirs == + user_target_schema.include_dirs)) { + target_.dirty_ = true; + target_.DirChanged(); + } else if (!(load_target_schema.headers == user_target_schema.headers) || + !(load_target_schema.pchs == user_target_schema.pchs)) { + target_.dirty_ = true; + target_.PathChanged(); + } else if (!load_target_schema.pch_compiled) { + // TODO, Replace this with fs::exists to check if compiled pch file is + // present or no target_.dirty_ = true; } } @@ -162,11 +167,9 @@ std::string CompilePch::ConstructCompileCommand() const { void CompilePch::PreCompile() { auto &target_user_schema = target_.user_; - target_user_schema.internal_headers = - internal::path_schema_convert(target_user_schema.headers); + target_user_schema.headers.ComputeHashForAll(); - target_user_schema.internal_pchs = - internal::path_schema_convert(target_user_schema.pchs); + target_user_schema.pchs.ComputeHashForAll(); } } // namespace buildcc::internal diff --git a/buildcc/lib/target/src/target/friend/link_target.cpp b/buildcc/lib/target/src/target/friend/link_target.cpp index 8e1f4b8b..fb5219ab 100644 --- a/buildcc/lib/target/src/target/friend/link_target.cpp +++ b/buildcc/lib/target/src/target/friend/link_target.cpp @@ -41,7 +41,8 @@ void LinkTarget::CacheLinkCommand() { {kOutput, output_target}, {kCompiledSources, aggregated_compiled_sources}, {kLibDeps, - fmt::format("{} {}", internal::aggregate(target_user_schema.libs), + fmt::format("{} {}", + internal::aggregate(target_user_schema.libs.GetPaths()), internal::aggregate(target_user_schema.external_libs))}, }); } @@ -59,11 +60,9 @@ fs::path LinkTarget::ConstructOutputPath() const { void LinkTarget::PreLink() { auto &target_user_schema = target_.user_; - target_user_schema.internal_libs = - path_schema_convert(target_user_schema.libs); + target_user_schema.libs.ComputeHashForAll(); - target_user_schema.internal_link_dependencies = - path_schema_convert(target_user_schema.link_dependencies); + target_user_schema.link_dependencies.ComputeHashForAll(); } void LinkTarget::BuildLink() { @@ -76,22 +75,27 @@ void LinkTarget::BuildLink() { if (!serialization.IsLoaded()) { target_.dirty_ = true; } else { - target_.RecheckFlags(target_load_schema.link_flags, - target_user_schema.link_flags); - target_.RecheckDirs(target_load_schema.lib_dirs, - target_user_schema.lib_dirs); - target_.RecheckExternalLib(target_load_schema.external_libs, - target_user_schema.external_libs); - target_.RecheckPaths(target_load_schema.internal_link_dependencies, - target_user_schema.internal_link_dependencies); - path_unordered_set target_loaded_libs( - target_load_schema.internal_libs.begin(), - target_load_schema.internal_libs.end()); - path_unordered_set target_user_libs( - target_user_schema.internal_libs.begin(), - target_user_schema.internal_libs.end()); - target_.RecheckPaths(target_loaded_libs, target_user_libs); - if (!target_load_schema.target_linked) { + if (target_.dirty_) { + // Skip all the other else if checks + } else if (!(target_load_schema.link_flags == + target_user_schema.link_flags)) { + target_.dirty_ = true; + target_.FlagChanged(); + } else if (!(target_load_schema.lib_dirs == target_user_schema.lib_dirs)) { + target_.dirty_ = true; + target_.DirChanged(); + } else if (!(target_load_schema.external_libs == + target_user_schema.external_libs)) { + target_.dirty_ = true; + target_.ExternalLibChanged(); + } else if (!(target_load_schema.link_dependencies == + target_user_schema.link_dependencies) || + !(target_load_schema.libs == target_user_schema.libs)) { + target_.dirty_ = true; + target_.PathChanged(); + } else if (!target_load_schema.target_linked) { + // TODO, Replace this with fs::exists to check if linked target is present + // or no target_.dirty_ = true; } } diff --git a/buildcc/lib/target/src/target/recheck_states.cpp b/buildcc/lib/target/src/target/recheck_states.cpp index 42bf53c0..4285fe0f 100644 --- a/buildcc/lib/target/src/target/recheck_states.cpp +++ b/buildcc/lib/target/src/target/recheck_states.cpp @@ -30,6 +30,7 @@ void Target::PathRemoved() {} void Target::PathAdded() {} void Target::PathUpdated() {} +void Target::PathChanged() {} void Target::DirChanged() {} void Target::FlagChanged() {} void Target::ExternalLibChanged() {} diff --git a/buildcc/lib/target/src/target/target.cpp b/buildcc/lib/target/src/target/target.cpp index 5958b556..48481daf 100644 --- a/buildcc/lib/target/src/target/target.cpp +++ b/buildcc/lib/target/src/target/target.cpp @@ -61,34 +61,6 @@ void Target::Initialize() { tf_.name(path); } -// Rechecks -void Target::RecheckPaths(const internal::path_unordered_set &previous_path, - const internal::path_unordered_set ¤t_path) { - BuilderInterface::RecheckPaths( - previous_path, current_path, [&]() { PathRemoved(); }, - [&]() { PathAdded(); }, [&]() { PathUpdated(); }); -} - -void Target::RecheckDirs(const fs_unordered_set &previous_dirs, - const fs_unordered_set ¤t_dirs) { - RecheckChanged(previous_dirs, current_dirs, - std::bind(&Target::DirChanged, this)); -} - -void Target::RecheckFlags( - const std::unordered_set &previous_flags, - const std::unordered_set ¤t_flags) { - RecheckChanged(previous_flags, current_flags, - std::bind(&Target::FlagChanged, this)); -} - -void Target::RecheckExternalLib( - const std::vector &previous_external_libs, - const std::vector ¤t_external_libs) { - RecheckChanged(previous_external_libs, current_external_libs, - std::bind(&Target::ExternalLibChanged, this)); -} - env::optional Target::SelectCompileFlags(FileExt ext) const { switch (ext) { case FileExt::Asm: diff --git a/buildcc/lib/target/src/target/tasks.cpp b/buildcc/lib/target/src/target/tasks.cpp index 50a59376..ef9f3e04 100644 --- a/buildcc/lib/target/src/target/tasks.cpp +++ b/buildcc/lib/target/src/target/tasks.cpp @@ -59,8 +59,8 @@ void CompilePch::Task() { // For Graph generation for (const auto &p : target_.GetPchFiles()) { - std::string name = - fmt::format("{}", p.lexically_relative(Project::GetRootDir())); + std::string name = fmt::format( + "{}", fs::path(p).lexically_relative(Project::GetRootDir())); subflow.placeholder().name(name); } }); @@ -83,25 +83,27 @@ void CompileObject::Task() { return; } - std::vector selected_source_files; - std::vector selected_dummy_source_files; + std::vector selected_source_files; + std::vector selected_dummy_source_files; try { BuildObjectCompile(selected_source_files, selected_dummy_source_files); - for (const auto &piter : selected_dummy_source_files) { - target_.serialization_.AddSource(piter); + for (const auto &path_info : selected_dummy_source_files) { + target_.serialization_.AddSource(path_info.path, path_info.hash); } - for (const auto &s : selected_source_files) { + for (const auto &path_info : selected_source_files) { std::string name = fmt::format( - "{}", s.pathname.lexically_relative(Project::GetRootDir())); + "{}", + fs::path(path_info.path).lexically_relative(Project::GetRootDir())); (void)subflow - .emplace([this, s]() { + .emplace([this, path_info]() { try { - bool success = - env::Command::Execute(GetObjectData(s.pathname).command); + bool success = env::Command::Execute( + GetObjectData(path_info.path).command); env::assert_fatal(success, "Could not compile source"); - target_.serialization_.AddSource(s); + target_.serialization_.AddSource(path_info.path, + path_info.hash); } catch (...) { env::set_task_state(env::TaskState::FAILURE); } @@ -110,9 +112,10 @@ void CompileObject::Task() { } // For graph generation - for (const auto &ds : selected_dummy_source_files) { - std::string name = fmt::format( - "{}", ds.pathname.lexically_relative(Project::GetRootDir())); + for (const auto &dummy_path_info : selected_dummy_source_files) { + std::string name = + fmt::format("{}", fs::path(dummy_path_info.path) + .lexically_relative(Project::GetRootDir())); (void)subflow.placeholder().name(name); } } catch (...) { diff --git a/buildcc/lib/target/test/path/CMakeLists.txt b/buildcc/lib/target/test/path/CMakeLists.txt deleted file mode 100644 index 04d8d9dc..00000000 --- a/buildcc/lib/target/test/path/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -configure_file(constants.h.in ${CMAKE_CURRENT_BINARY_DIR}/generated/constants.h @ONLY) - -set(TEST_NAME "test_path") -add_executable( - ${TEST_NAME} - ${TEST_NAME}.cpp -) -target_include_directories(${TEST_NAME} PRIVATE - ${TARGET_DIR}/include - ${CMAKE_CURRENT_BINARY_DIR}/generated -) -target_link_libraries(${TEST_NAME} PRIVATE - mock_env - mock_schema - - CppUTest - CppUTestExt - ${TEST_LINK_LIBS} -) -target_compile_options(${TEST_NAME} PRIVATE ${TEST_COMPILE_FLAGS}) -target_link_options(${TEST_NAME} PRIVATE ${TEST_LINK_FLAGS}) - -add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME}) diff --git a/buildcc/lib/target/test/path/constants.h.in b/buildcc/lib/target/test/path/constants.h.in deleted file mode 100644 index 9da788ce..00000000 --- a/buildcc/lib/target/test/path/constants.h.in +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -// clang-format off -inline constexpr char const *BUILD_SCRIPT_SOURCE = "@CMAKE_CURRENT_SOURCE_DIR@"; diff --git a/buildcc/lib/target/test/path/path_main.cpp b/buildcc/lib/target/test/path/path_main.cpp deleted file mode 100644 index 18a69789..00000000 --- a/buildcc/lib/target/test/path/path_main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main() { - std::cout << "Hello World from test" << std::endl; - return 0; -} diff --git a/buildcc/lib/target/test/path/test_path.cpp b/buildcc/lib/target/test/path/test_path.cpp deleted file mode 100644 index 50249313..00000000 --- a/buildcc/lib/target/test/path/test_path.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// Internal -#include "schema/path.h" - -#include "env/assert_fatal.h" - -#include "constants.h" - -#include -#include - -// NOTE, Make sure all these includes are AFTER the system and header includes -#include "CppUTest/CommandLineTestRunner.h" -#include "CppUTest/MemoryLeakDetectorNewMacros.h" -#include "CppUTest/TestHarness.h" -#include "CppUTest/Utest.h" - -// clang-format off -TEST_GROUP(PathTestGroup) -{ -}; -// clang-format on - -static const auto current_file_path = - (fs::path(BUILD_SCRIPT_SOURCE) / "path_main.cpp").make_preferred(); - -TEST(PathTestGroup, Path_ExistingPathStaticConstructor) { - auto existing_path = - buildcc::internal::Path::CreateExistingPath(current_file_path); - STRCMP_EQUAL(existing_path.pathname.string().c_str(), - current_file_path.string().c_str()); - // * NOTE, Last write timestamp changes whenever we resave or re-download - // This would not work well with Git - // UNSIGNED_LONGLONGS_EQUAL(existing_path.last_write_timestamp, - // 13623997187709551616ULL); -} - -TEST(PathTestGroup, Path_ExistingPathStaticConstructor_ThrowFileException) { - CHECK_THROWS(std::exception, buildcc::internal::Path::CreateExistingPath( - "random_path_main.cpp")); -} - -TEST(PathTestGroup, PathConstructor_NewPathStaticConstructor) { - buildcc::internal::Path p = - buildcc::internal::Path("random_path_main.cpp", 12345ULL); - STRCMP_EQUAL(p.pathname.string().c_str(), "random_path_main.cpp"); - UNSIGNED_LONGLONGS_EQUAL(p.last_write_timestamp, 12345ULL); -} - -TEST(PathTestGroup, Path_EqualityOperator) { - buildcc::internal::Path p = - buildcc::internal::Path::CreateExistingPath(current_file_path); - STRCMP_EQUAL(p.pathname.string().c_str(), current_file_path.string().c_str()); - - buildcc::internal::Path newp = - buildcc::internal::Path(current_file_path, 12345ULL); - - // NOTE, Equality does not match the last_write_timestamp - // ONLY matches the string - CHECK(p == newp); - CHECK(p == current_file_path); - CHECK(p == current_file_path); -} - -TEST(PathTestGroup, Path_UnorderedSet) { - std::unordered_set - unique_paths; - - // Check inserts - CHECK_TRUE(unique_paths - .insert(buildcc::internal::Path::CreateExistingPath( - current_file_path)) - .second); - CHECK_FALSE( - unique_paths.insert(buildcc::internal::Path(current_file_path, 12345ULL)) - .second); - CHECK_TRUE( - unique_paths - .insert(buildcc::internal::Path("random_path_main.cpp", 98765ULL)) - .second); - - // Check finds - // * NOTE, Only matches pathname - CHECK_FALSE(unique_paths.find(buildcc::internal::Path::CreateExistingPath( - current_file_path)) == unique_paths.end()); - - CHECK_FALSE(unique_paths.find(buildcc::internal::Path( - current_file_path, 1111ULL)) == unique_paths.end()); - CHECK_FALSE(unique_paths.find(buildcc::internal::Path( - "random_path_main.cpp", 12345ULL)) == unique_paths.end()); - CHECK_TRUE(unique_paths.find(buildcc::internal::Path( - "incorrect_path_main.cpp", 0000ULL)) == unique_paths.end()); -} - -int main(int ac, char **av) { - return CommandLineTestRunner::RunAllTests(ac, av); -} diff --git a/buildcc/lib/target/test/target/CMakeLists.txt b/buildcc/lib/target/test/target/CMakeLists.txt index 46a1a03f..8e73ca20 100644 --- a/buildcc/lib/target/test/target/CMakeLists.txt +++ b/buildcc/lib/target/test/target/CMakeLists.txt @@ -18,17 +18,11 @@ target_link_libraries(test_toolchain_flag_api PRIVATE target_interface) add_test(NAME test_toolchain_flag_api COMMAND test_toolchain_flag_api) # Interfaces -add_executable(test_builder_interface - test_builder_interface.cpp -) -target_link_libraries(test_builder_interface PRIVATE target_interface) - add_executable(test_serialization_interface test_serialization_interface.cpp ) target_link_libraries(test_serialization_interface PRIVATE target_interface) -add_test(NAME test_builder_interface COMMAND test_builder_interface) add_test(NAME test_serialization_interface COMMAND test_serialization_interface WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/buildcc/lib/target/test/target/test_builder_interface.cpp b/buildcc/lib/target/test/target/test_builder_interface.cpp deleted file mode 100644 index 5e59d9fe..00000000 --- a/buildcc/lib/target/test/target/test_builder_interface.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include "target/interface/builder_interface.h" - -#include "schema/path.h" - -// NOTE, Make sure all these includes are AFTER the system and header includes -#include "CppUTest/CommandLineTestRunner.h" -#include "CppUTest/MemoryLeakDetectorNewMacros.h" -#include "CppUTest/TestHarness.h" -#include "CppUTest/Utest.h" - -// TestBuilderInterface - -class TestBuilderInterface : public buildcc::internal::BuilderInterface { -public: - void Build() override {} - - void RecheckChangedIncorrectCb() { - BuilderInterface::RecheckChanged(previous_, current_, - std::function()); - } - void RecheckPathIncorrectRemoveCb() { - BuilderInterface::RecheckPaths(previous_, current_, - std::function()); - } - void RecheckPathIncorrectAddCb() { - BuilderInterface::RecheckPaths( - previous_, current_, []() {}, std::function()); - } - void RecheckPathIncorrectUpdateCb() { - BuilderInterface::RecheckPaths( - previous_, current_, []() {}, []() {}, std::function()); - } - -private: - buildcc::internal::path_unordered_set previous_; - buildcc::internal::path_unordered_set current_; -}; - -// clang-format off -TEST_GROUP(TestBuilderInterfaceGroup) -{ -}; -// clang-format on - -TEST(TestBuilderInterfaceGroup, IncorrectRecheckChangedCb) { - TestBuilderInterface tbi; - CHECK_THROWS(std::exception, tbi.RecheckChangedIncorrectCb()); -} - -TEST(TestBuilderInterfaceGroup, IncorrectRemoveRecheckCb) { - TestBuilderInterface tbi; - CHECK_THROWS(std::exception, tbi.RecheckPathIncorrectRemoveCb()); -} - -TEST(TestBuilderInterfaceGroup, IncorrectAddRecheckCb) { - TestBuilderInterface tbi; - CHECK_THROWS(std::exception, tbi.RecheckPathIncorrectAddCb()); -} - -TEST(TestBuilderInterfaceGroup, IncorrectUpdateRecheckCb) { - TestBuilderInterface tbi; - CHECK_THROWS(std::exception, tbi.RecheckPathIncorrectUpdateCb()); -} - -TEST(TestBuilderInterfaceGroup, CheckChanged) { - std::vector previous{"", "v1"}; - std::vector current{"", "v1"}; - CHECK_FALSE(buildcc::internal::CheckChanged(previous, current)); - - current.clear(); - current.push_back(""); - CHECK_TRUE(buildcc::internal::CheckChanged(previous, current)); -} - -TEST(TestBuilderInterfaceGroup, CheckPaths) { - { - auto pathstate = buildcc::internal::CheckPaths( - { - buildcc::internal::Path("", 0x1234), - buildcc::internal::Path("v1", 0x2345), - }, - { - buildcc::internal::Path("", 0x1234), - buildcc::internal::Path("v1", 0x2345), - }); - CHECK_TRUE(pathstate == buildcc::internal::PathState::kNoChange); - } - - { - auto pathstate = buildcc::internal::CheckPaths( - { - buildcc::internal::Path("", 0x1234), - buildcc::internal::Path("v1", 0x2345), - }, - { - buildcc::internal::Path("", 0x1234), - }); - CHECK_TRUE(pathstate == buildcc::internal::PathState::kRemoved); - } - - { - auto pathstate = buildcc::internal::CheckPaths( - { - buildcc::internal::Path("", 0x1234), - buildcc::internal::Path("v1", 0x2345), - }, - { - buildcc::internal::Path("", 0x1234), - buildcc::internal::Path("v1", 0x2345), - buildcc::internal::Path("v2", 0x3456), - }); - CHECK_TRUE(pathstate == buildcc::internal::PathState::kAdded); - } - - { - auto pathstate = buildcc::internal::CheckPaths( - { - buildcc::internal::Path("", 0x1234), - buildcc::internal::Path("v1", 0x2345), - }, - { - buildcc::internal::Path("", 0x1234), - buildcc::internal::Path("v1", 0x3456), - }); - CHECK_TRUE(pathstate == buildcc::internal::PathState::kUpdated); - } -} - -int main(int ac, char **av) { - return CommandLineTestRunner::RunAllTests(ac, av); -} diff --git a/buildcc/lib/target/test/target/test_custom_generator.cpp b/buildcc/lib/target/test/target/test_custom_generator.cpp index f4293c9f..38c2c317 100644 --- a/buildcc/lib/target/test/target/test_custom_generator.cpp +++ b/buildcc/lib/target/test/target/test_custom_generator.cpp @@ -375,7 +375,7 @@ TEST(CustomGeneratorTestGroup, RealGenerate_Update_Success) { CHECK_EQUAL(imap.at("id2").outputs.GetPaths().size(), 1); STRCMP_EQUAL(std::to_string(last_write_timestamp).c_str(), - imap.at("id2").inputs.GetPathInfos().begin()->second.c_str()); + imap.at("id2").inputs.GetPathInfos()[0].hash.c_str()); CHECK(buildcc::env::get_task_state() == buildcc::env::TaskState::SUCCESS); } diff --git a/buildcc/lib/target/test/target/test_target_external_lib.cpp b/buildcc/lib/target/test/target/test_target_external_lib.cpp index 404f7330..e6f76cef 100644 --- a/buildcc/lib/target/test/target/test_target_external_lib.cpp +++ b/buildcc/lib/target/test/target/test_target_external_lib.cpp @@ -57,7 +57,7 @@ TEST(TargetTestExternalLib, TestAddLibDir) { exe.GetTargetBuildDir() / (std::string(EXENAME) + ".bin")); bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(serialization.GetLoad().lib_dirs.size(), 1); + CHECK_EQUAL(serialization.GetLoad().lib_dirs.GetPaths().size(), 1); CHECK_EQUAL(serialization.GetLoad().external_libs.size(), 0); } @@ -86,7 +86,7 @@ TEST(TargetTestExternalLib, TestAddExternalLibDep_Simple) { bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(serialization.GetLoad().lib_dirs.size(), 1); + CHECK_EQUAL(serialization.GetLoad().lib_dirs.GetPaths().size(), 1); CHECK_EQUAL(serialization.GetLoad().external_libs.size(), 1); } diff --git a/buildcc/lib/target/test/target/test_target_flags.cpp b/buildcc/lib/target/test/target/test_target_flags.cpp index 72933547..af1d1b91 100644 --- a/buildcc/lib/target/test/target/test_target_flags.cpp +++ b/buildcc/lib/target/test/target/test_target_flags.cpp @@ -31,6 +31,7 @@ static buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", TEST_GROUP(TargetTestPreprocessorFlagGroup) { void teardown() { + mock().checkExpectations(); mock().clear(); } }; @@ -147,27 +148,54 @@ TEST(TargetTestCommonCompileFlagsGroup, Target_AddCommonCompileFlag) { // Delete fs::remove_all(intermediate_path); - buildcc::BaseTarget simple(NAME, buildcc::TargetType::Executable, gcc, - "data"); - simple.AddSource(DUMMY_MAIN); - simple.AddCommonCompileFlag("-O0"); - simple.AddCommonCompileFlag("-g"); + { + buildcc::BaseTarget simple(NAME, buildcc::TargetType::Executable, gcc, + "data"); + simple.AddSource(DUMMY_MAIN); + simple.AddCommonCompileFlag("-O0"); + simple.AddCommonCompileFlag("-g"); - buildcc::env::m::CommandExpect_Execute(1, true); - buildcc::env::m::CommandExpect_Execute(1, true); - simple.Build(); - buildcc::m::TargetRunner(simple); - CHECK_TRUE(simple.IsBuilt()); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + simple.Build(); + buildcc::m::TargetRunner(simple); + CHECK_TRUE(simple.IsBuilt()); - mock().checkExpectations(); + mock().checkExpectations(); - // Verify binary - buildcc::internal::TargetSerialization serialization( - simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); - bool loaded = serialization.LoadFromFile(); - CHECK_TRUE(loaded); + // Verify binary + buildcc::internal::TargetSerialization serialization( + simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); + CHECK_TRUE(loaded); + + CHECK_EQUAL(serialization.GetLoad().common_compile_flags.size(), 2); + } + + // Trigger Rebuild for Common Compile flag + { + buildcc::BaseTarget simple(NAME, buildcc::TargetType::Executable, gcc, + "data"); + simple.AddSource(DUMMY_MAIN); + simple.AddCommonCompileFlag("-O0"); + + buildcc::m::TargetExpect_FlagChanged(1, &simple); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + simple.Build(); + buildcc::m::TargetRunner(simple); + CHECK_TRUE(simple.IsBuilt()); + + mock().checkExpectations(); + + // Verify binary + buildcc::internal::TargetSerialization serialization( + simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); + CHECK_TRUE(loaded); - CHECK_EQUAL(serialization.GetLoad().common_compile_flags.size(), 2); + CHECK_EQUAL(serialization.GetLoad().common_compile_flags.size(), 1); + } } TEST(TargetTestCommonCompileFlagsGroup, Target_ChangedCommonCompileFlag) { @@ -476,26 +504,53 @@ TEST(TargetTestCppCompileFlagsGroup, Target_AddCompileFlag) { // Delete fs::remove_all(intermediate_path); - buildcc::BaseTarget simple(NAME, buildcc::TargetType::Executable, gcc, - "data"); - simple.AddSource(DUMMY_MAIN); - simple.AddCppCompileFlag("-std=c++17"); + { + buildcc::BaseTarget simple(NAME, buildcc::TargetType::Executable, gcc, + "data"); + simple.AddSource(DUMMY_MAIN); + simple.AddCppCompileFlag("-std=c++17"); - buildcc::env::m::CommandExpect_Execute(1, true); - buildcc::env::m::CommandExpect_Execute(1, true); - simple.Build(); - buildcc::m::TargetRunner(simple); - CHECK_TRUE(simple.IsBuilt()); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + simple.Build(); + buildcc::m::TargetRunner(simple); + CHECK_TRUE(simple.IsBuilt()); - mock().checkExpectations(); + mock().checkExpectations(); - // Verify binary - buildcc::internal::TargetSerialization serialization( - simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); - bool loaded = serialization.LoadFromFile(); - CHECK_TRUE(loaded); + // Verify binary + buildcc::internal::TargetSerialization serialization( + simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); + CHECK_TRUE(loaded); + + CHECK_EQUAL(serialization.GetLoad().cpp_compile_flags.size(), 1); + } + + // Trigger rebuild for Cpp Compile flag + { + buildcc::BaseTarget simple(NAME, buildcc::TargetType::Executable, gcc, + "data"); + simple.AddSource(DUMMY_MAIN); + simple.AddCppCompileFlag("-std=c++20"); - CHECK_EQUAL(serialization.GetLoad().cpp_compile_flags.size(), 1); + buildcc::m::TargetExpect_FlagChanged(1, &simple); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + simple.Build(); + buildcc::m::TargetRunner(simple); + CHECK_TRUE(simple.IsBuilt()); + + mock().checkExpectations(); + + // Verify binary + buildcc::internal::TargetSerialization serialization( + simple.GetTargetBuildDir() / (std::string(NAME) + ".bin")); + bool loaded = serialization.LoadFromFile(); + CHECK_TRUE(loaded); + + CHECK_EQUAL(serialization.GetLoad().cpp_compile_flags.size(), 1); + } } TEST(TargetTestCppCompileFlagsGroup, Target_ChangedCompileFlag) { diff --git a/buildcc/lib/target/test/target/test_target_include_dir.cpp b/buildcc/lib/target/test/target/test_target_include_dir.cpp index ea8633b0..2636f52e 100644 --- a/buildcc/lib/target/test/target/test_target_include_dir.cpp +++ b/buildcc/lib/target/test/target/test_target_include_dir.cpp @@ -94,12 +94,14 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { // Delete fs::remove_all(intermediate_path); - auto dummy_c_file = buildcc::internal::Path::CreateExistingPath( - (source_path / DUMMY_MAIN_C).make_preferred().string()); - auto include_header_file = buildcc::internal::Path::CreateExistingPath( - (source_path / INCLUDE_HEADER_SOURCE).make_preferred().string()); - auto include_header_path = - (source_path / RELATIVE_INCLUDE_DIR).make_preferred(); + auto dummy_c_file = buildcc::internal::PathInfo::ToPathString( + fs::path(source_path / DUMMY_MAIN_C).string()); + + auto include_header_file = buildcc::internal::PathInfo::ToPathString( + fs::path(source_path / INCLUDE_HEADER_SOURCE).string()); + + auto include_header_path = buildcc::internal::PathInfo::ToPathString( + fs::path(source_path / RELATIVE_INCLUDE_DIR).string()); { buildcc::BaseTarget include_compile(NAME, buildcc::TargetType::Executable, @@ -107,7 +109,7 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { include_compile.AddSource(DUMMY_MAIN_C); include_compile.AddSource(INCLUDE_HEADER_SOURCE); include_compile.AddIncludeDir(RELATIVE_INCLUDE_DIR); - // Duplicate include directory + // Duplicate include directory (will be reflected) include_compile.AddIncludeDir(RELATIVE_INCLUDE_DIR); buildcc::env::m::CommandExpect_Execute(2, true); @@ -119,18 +121,21 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { intermediate_path / (std::string(NAME) + ".bin")); bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = serialization.GetLoad().internal_sources; - const auto &loaded_dirs = serialization.GetLoad().include_dirs; + const auto &loaded_sources = + serialization.GetLoad().sources.GetUnorderedPathInfos(); + const auto &loaded_dirs = serialization.GetLoad().include_dirs.GetPaths(); CHECK_EQUAL(loaded_sources.size(), 2); - CHECK_EQUAL(loaded_dirs.size(), 1); + CHECK_EQUAL(loaded_dirs.size(), 2); CHECK_FALSE(loaded_sources.find(dummy_c_file) == loaded_sources.end()); CHECK_FALSE(loaded_sources.find(include_header_file) == loaded_sources.end()); - CHECK_FALSE(loaded_dirs.find(include_header_path.string()) == - loaded_dirs.end()); + std::unordered_set unordered_loaded_dirs(loaded_dirs.begin(), + loaded_dirs.end()); + CHECK_FALSE(unordered_loaded_dirs.find(include_header_path) == + unordered_loaded_dirs.end()); } { // * 1 Adding new include directory @@ -152,8 +157,9 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { intermediate_path / (std::string(NAME) + ".bin")); bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = serialization.GetLoad().internal_sources; - const auto &loaded_dirs = serialization.GetLoad().include_dirs; + const auto &loaded_sources = + serialization.GetLoad().sources.GetUnorderedPathInfos(); + const auto &loaded_dirs = serialization.GetLoad().include_dirs.GetPaths(); CHECK_EQUAL(loaded_sources.size(), 2); CHECK_EQUAL(loaded_dirs.size(), 2); @@ -161,8 +167,11 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { CHECK_FALSE(loaded_sources.find(dummy_c_file) == loaded_sources.end()); CHECK_FALSE(loaded_sources.find(include_header_file) == loaded_sources.end()); - CHECK_FALSE(loaded_dirs.find(include_header_path.string()) == - loaded_dirs.end()); + + std::unordered_set unordered_loaded_dirs(loaded_dirs.begin(), + loaded_dirs.end()); + CHECK_FALSE(unordered_loaded_dirs.find(include_header_path) == + unordered_loaded_dirs.end()); } { // * Remove include directory @@ -182,8 +191,9 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { intermediate_path / (std::string(NAME) + ".bin")); bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = serialization.GetLoad().internal_sources; - const auto &loaded_dirs = serialization.GetLoad().include_dirs; + const auto &loaded_sources = + serialization.GetLoad().sources.GetUnorderedPathInfos(); + const auto &loaded_dirs = serialization.GetLoad().include_dirs.GetPaths(); CHECK_EQUAL(loaded_sources.size(), 2); CHECK_EQUAL(loaded_dirs.size(), 1); @@ -191,8 +201,11 @@ TEST(TargetTestIncludeDirGroup, TargetBuildIncludeDir) { CHECK_FALSE(loaded_sources.find(dummy_c_file) == loaded_sources.end()); CHECK_FALSE(loaded_sources.find(include_header_file) == loaded_sources.end()); - CHECK_FALSE(loaded_dirs.find(include_header_path.string()) == - loaded_dirs.end()); + + std::unordered_set unordered_loaded_dirs(loaded_dirs.begin(), + loaded_dirs.end()); + CHECK_FALSE(unordered_loaded_dirs.find(include_header_path) == + unordered_loaded_dirs.end()); } mock().checkExpectations(); @@ -212,10 +225,6 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { // Delete fs::remove_all(intermediate_path); - auto dummy_c_file = - buildcc::internal::Path::CreateExistingPath((source_path / DUMMY_MAIN_C)); - auto include_header_file = buildcc::internal::Path::CreateExistingPath( - (source_path / INCLUDE_HEADER_SOURCE)); auto include_header_path = (source_path / RELATIVE_INCLUDE_DIR).make_preferred(); @@ -236,9 +245,10 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { intermediate_path / (std::string(NAME) + ".bin")); bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - CHECK_EQUAL(serialization.GetLoad().internal_sources.size(), 2); - CHECK_EQUAL(serialization.GetLoad().include_dirs.size(), 1); - CHECK_EQUAL(serialization.GetLoad().internal_headers.size(), 0); + CHECK_EQUAL(serialization.GetLoad().sources.GetUnorderedPathInfos().size(), + 2); + CHECK_EQUAL(serialization.GetLoad().include_dirs.GetPaths().size(), 1); + CHECK_EQUAL(serialization.GetLoad().headers.GetPaths().size(), 0); } // Add header @@ -260,9 +270,10 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { intermediate_path / (std::string(NAME) + ".bin")); bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - CHECK_EQUAL(serialization.GetLoad().internal_sources.size(), 2); - CHECK_EQUAL(serialization.GetLoad().include_dirs.size(), 1); - CHECK_EQUAL(serialization.GetLoad().internal_headers.size(), 1); + CHECK_EQUAL(serialization.GetLoad().sources.GetUnorderedPathInfos().size(), + 2); + CHECK_EQUAL(serialization.GetLoad().include_dirs.GetPaths().size(), 1); + CHECK_EQUAL(serialization.GetLoad().headers.GetPaths().size(), 1); } // Update header @@ -290,9 +301,10 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { intermediate_path / (std::string(NAME) + ".bin")); bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - CHECK_EQUAL(serialization.GetLoad().internal_sources.size(), 2); - CHECK_EQUAL(serialization.GetLoad().include_dirs.size(), 1); - CHECK_EQUAL(serialization.GetLoad().internal_headers.size(), 1); + CHECK_EQUAL(serialization.GetLoad().sources.GetUnorderedPathInfos().size(), + 2); + CHECK_EQUAL(serialization.GetLoad().include_dirs.GetPaths().size(), 1); + CHECK_EQUAL(serialization.GetLoad().headers.GetPaths().size(), 1); } // Remove header @@ -313,9 +325,10 @@ TEST(TargetTestIncludeDirGroup, TargetBuildHeaderFile) { intermediate_path / (std::string(NAME) + ".bin")); bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - CHECK_EQUAL(serialization.GetLoad().internal_sources.size(), 2); - CHECK_EQUAL(serialization.GetLoad().include_dirs.size(), 1); - CHECK_EQUAL(serialization.GetLoad().internal_headers.size(), 0); + CHECK_EQUAL(serialization.GetLoad().sources.GetUnorderedPathInfos().size(), + 2); + CHECK_EQUAL(serialization.GetLoad().include_dirs.GetPaths().size(), 1); + CHECK_EQUAL(serialization.GetLoad().headers.GetPaths().size(), 0); } mock().checkExpectations(); diff --git a/buildcc/lib/target/test/target/test_target_lib_dep.cpp b/buildcc/lib/target/test/target/test_target_lib_dep.cpp index 2f83d5b2..21078e7d 100644 --- a/buildcc/lib/target/test/target/test_target_lib_dep.cpp +++ b/buildcc/lib/target/test/target/test_target_lib_dep.cpp @@ -60,8 +60,8 @@ TEST(TargetTestLibDep, StaticLibrary_SimpleBuildTest) { bool loaded = serialization.LoadFromFile(); CHECK_TRUE(loaded); - CHECK_EQUAL(serialization.GetLoad().internal_sources.size(), 1); - CHECK_EQUAL(serialization.GetLoad().include_dirs.size(), 1); + CHECK_EQUAL(serialization.GetLoad().sources.GetPathInfos().size(), 1); + CHECK_EQUAL(serialization.GetLoad().include_dirs.GetPaths().size(), 1); } TEST(TargetTestLibDep, TargetDep_RebuildTest) { diff --git a/buildcc/lib/target/test/target/test_target_pch.cpp b/buildcc/lib/target/test/target/test_target_pch.cpp index 64fdbd8b..57385eb5 100644 --- a/buildcc/lib/target/test/target/test_target_pch.cpp +++ b/buildcc/lib/target/test/target/test_target_pch.cpp @@ -25,6 +25,7 @@ TEST_GROUP(TargetPchTestGroup) { void teardown() { + mock().checkExpectations(); mock().clear(); } }; @@ -246,24 +247,237 @@ TEST(TargetPchTestGroup, Target_AddPch_CppRebuild) { mock().checkExpectations(); } -TEST(TargetPchTestGroup, Target_AddPchCompileFlag_Build) { - constexpr const char *const NAME = "AddPchCompileFlag_Build.exe"; +TEST(TargetPchTestGroup, Target_AddPch_IncludeDirsRebuild) { + constexpr const char *const NAME = "AddPch_IncludeDirsRebuild.exe"; - buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, - "data"); - target.AddPchCompileFlag("-H"); - target.AddPch("pch/pch_header_1.h"); - target.AddPch("pch/pch_header_2.h"); + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddIncludeDir("pch"); - buildcc::env::m::CommandExpect_Execute(1, true); - buildcc::env::m::CommandExpect_Execute(1, true); - target.Build(); - buildcc::m::TargetRunner(target); - bool exists = fs::exists(target.GetPchHeaderPath()); - CHECK_TRUE(exists); - CHECK_EQUAL(target.GetPchCompileFlags().size(), 1); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } - mock().checkExpectations(); + // No Change + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddIncludeDir("pch"); + + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Remove + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPch("pch/pch_header_1.h"); + // target.AddIncludeDir("pch"); + + buildcc::m::TargetExpect_DirChanged(1, &target); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Added + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddIncludeDir("pch"); + + buildcc::m::TargetExpect_DirChanged(1, &target); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } +} + +TEST(TargetPchTestGroup, Target_AddPch_HeadersRebuild) { + constexpr const char *const NAME = "AddPch_HeadersRebuild.exe"; + + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddHeader("pch/pch_header_1.h"); + + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // No Change + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddHeader("pch/pch_header_1.h"); + + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Remove + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPch("pch/pch_header_1.h"); + // target.AddHeader("pch/pch_header_1.h"); + + buildcc::m::TargetExpect_PathChanged(1, &target); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Added + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPch("pch/pch_header_1.h"); + target.AddHeader("pch/pch_header_1.h"); + + buildcc::m::TargetExpect_PathChanged(1, &target); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } +} + +TEST(TargetPchTestGroup, Target_AddPchs_FlagsRebuild) { + constexpr const char *const NAME = "Target_AddPchs_FlagsRebuild.exe"; + + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPch("pch/pch_header_1.h"); + + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Added Preprocessor flag + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPreprocessorFlag("-H"); + target.AddPch("pch/pch_header_1.h"); + + buildcc::m::TargetExpect_FlagChanged(1, &target); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Added CommonCompileFlag + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPreprocessorFlag("-H"); + target.AddCommonCompileFlag("-H"); + target.AddPch("pch/pch_header_1.h"); + + buildcc::m::TargetExpect_FlagChanged(1, &target); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Added PchCompileFlag + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPreprocessorFlag("-H"); + target.AddCommonCompileFlag("-H"); + target.AddPchCompileFlag("-H"); + target.AddPch("pch/pch_header_1.h"); + + buildcc::m::TargetExpect_FlagChanged(1, &target); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Added CCompileFlag + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPreprocessorFlag("-H"); + target.AddCommonCompileFlag("-H"); + target.AddPchCompileFlag("-H"); + target.AddCCompileFlag("-H"); + target.AddPch("pch/pch_header_1.h"); + + buildcc::m::TargetExpect_FlagChanged(1, &target); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } + + // Keep CCompileFlag, Added CppCompileFlag + { + buildcc::BaseTarget target(NAME, buildcc::TargetType::Executable, gcc, + "data"); + target.AddPreprocessorFlag("-H"); + target.AddCommonCompileFlag("-H"); + target.AddPchCompileFlag("-H"); + target.AddCCompileFlag("-H"); + target.AddCppCompileFlag("-H"); + target.AddPch("pch/pch_header_1.h"); + + buildcc::m::TargetExpect_FlagChanged(1, &target); + buildcc::env::m::CommandExpect_Execute(1, true); + buildcc::env::m::CommandExpect_Execute(1, true); + target.Build(); + buildcc::m::TargetRunner(target); + bool exists = fs::exists(target.GetPchHeaderPath()); + CHECK_TRUE(exists); + } } TEST(TargetPchTestGroup, Target_AddPchObjectFlag_Build) { diff --git a/buildcc/lib/target/test/target/test_target_source.cpp b/buildcc/lib/target/test/target/test_target_source.cpp index 8cd2f1f0..4e34eb28 100644 --- a/buildcc/lib/target/test/target/test_target_source.cpp +++ b/buildcc/lib/target/test/target/test_target_source.cpp @@ -111,10 +111,11 @@ TEST(TargetTestSourceGroup, Target_Build_SourceCompile) { bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = serialization.GetLoad().internal_sources; + const auto &loaded_sources = + serialization.GetLoad().sources.GetUnorderedPathInfos(); CHECK_EQUAL(loaded_sources.size(), 1); - auto dummy_file = buildcc::internal::Path::CreateExistingPath( - (source_path / DUMMY_MAIN).make_preferred().string()); + auto dummy_file = buildcc::internal::PathInfo::ToPathString( + fs::path(source_path / DUMMY_MAIN).string()); CHECK_FALSE(loaded_sources.find(dummy_file) == loaded_sources.end()); } @@ -129,12 +130,12 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { // Delete fs::remove_all(intermediate_path); - auto dummy_c_file = buildcc::internal::Path::CreateExistingPath( - (source_path / DUMMY_MAIN_C).make_preferred().string()); - auto dummy_cpp_file = buildcc::internal::Path::CreateExistingPath( - (source_path / DUMMY_MAIN_CPP).make_preferred().string()); - auto new_source_file = buildcc::internal::Path::CreateExistingPath( - (source_path / NEW_SOURCE).make_preferred().string()); + auto dummy_c_file = buildcc::internal::PathInfo::ToPathString( + (source_path / DUMMY_MAIN_C).string()); + auto dummy_cpp_file = buildcc::internal::PathInfo::ToPathString( + (source_path / DUMMY_MAIN_CPP).string()); + auto new_source_file = buildcc::internal::PathInfo::ToPathString( + (source_path / NEW_SOURCE).string()); { buildcc::BaseTarget simple(NAME, buildcc::TargetType::Executable, gcc, @@ -155,7 +156,8 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = serialization.GetLoad().internal_sources; + const auto &loaded_sources = + serialization.GetLoad().sources.GetUnorderedPathInfos(); CHECK_EQUAL(loaded_sources.size(), 2); CHECK_FALSE(loaded_sources.find(dummy_c_file) == loaded_sources.end()); @@ -187,7 +189,8 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = serialization.GetLoad().internal_sources; + const auto &loaded_sources = + serialization.GetLoad().sources.GetUnorderedPathInfos(); CHECK_EQUAL(loaded_sources.size(), 2); CHECK_FALSE(loaded_sources.find(dummy_cpp_file) == loaded_sources.end()); CHECK_FALSE(loaded_sources.find(new_source_file) == loaded_sources.end()); @@ -218,7 +221,8 @@ TEST(TargetTestSourceGroup, Target_Build_SourceRecompile) { bool is_loaded = serialization.LoadFromFile(); CHECK_TRUE(is_loaded); - const auto &loaded_sources = serialization.GetLoad().internal_sources; + const auto &loaded_sources = + serialization.GetLoad().sources.GetUnorderedPathInfos(); CHECK_EQUAL(loaded_sources.size(), 2); CHECK_FALSE(loaded_sources.find(dummy_cpp_file) == loaded_sources.end()); CHECK_FALSE(loaded_sources.find(new_source_file) == loaded_sources.end()); diff --git a/buildcc/lib/toolchain/include/toolchain/api/flag_api.h b/buildcc/lib/toolchain/include/toolchain/api/flag_api.h index 5953d243..7d79388f 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/flag_api.h +++ b/buildcc/lib/toolchain/include/toolchain/api/flag_api.h @@ -18,7 +18,7 @@ #define TOOLCHAIN_API_FLAG_API_H_ #include -#include +#include namespace buildcc::internal { @@ -28,81 +28,81 @@ template class FlagApi { public: void AddPreprocessorFlag(const std::string &flag) { auto &t = static_cast(*this); - t.user_.preprocessor_flags.insert(flag); + t.user_.preprocessor_flags.push_back(flag); } void AddCommonCompileFlag(const std::string &flag) { auto &t = static_cast(*this); - t.user_.common_compile_flags.insert(flag); + t.user_.common_compile_flags.push_back(flag); } void AddPchCompileFlag(const std::string &flag) { auto &t = static_cast(*this); - t.user_.pch_compile_flags.insert(flag); + t.user_.pch_compile_flags.push_back(flag); } void AddPchObjectFlag(const std::string &flag) { auto &t = static_cast(*this); - t.user_.pch_object_flags.insert(flag); + t.user_.pch_object_flags.push_back(flag); } void AddAsmCompileFlag(const std::string &flag) { auto &t = static_cast(*this); - t.user_.asm_compile_flags.insert(flag); + t.user_.asm_compile_flags.push_back(flag); } void AddCCompileFlag(const std::string &flag) { auto &t = static_cast(*this); - t.user_.c_compile_flags.insert(flag); + t.user_.c_compile_flags.push_back(flag); } void AddCppCompileFlag(const std::string &flag) { auto &t = static_cast(*this); - t.user_.cpp_compile_flags.insert(flag); + t.user_.cpp_compile_flags.push_back(flag); } void AddLinkFlag(const std::string &flag) { auto &t = static_cast(*this); - t.user_.link_flags.insert(flag); + t.user_.link_flags.push_back(flag); } // Getters - const std::unordered_set &GetPreprocessorFlags() const { + const std::vector &GetPreprocessorFlags() const { const auto &t = static_cast(*this); return t.user_.preprocessor_flags; } - const std::unordered_set &GetCommonCompileFlags() const { + const std::vector &GetCommonCompileFlags() const { const auto &t = static_cast(*this); return t.user_.common_compile_flags; } - const std::unordered_set &GetPchCompileFlags() const { + const std::vector &GetPchCompileFlags() const { const auto &t = static_cast(*this); return t.user_.pch_compile_flags; } - const std::unordered_set &GetPchObjectFlags() const { + const std::vector &GetPchObjectFlags() const { const auto &t = static_cast(*this); return t.user_.pch_object_flags; } - const std::unordered_set &GetAsmCompileFlags() const { + const std::vector &GetAsmCompileFlags() const { const auto &t = static_cast(*this); return t.user_.asm_compile_flags; } - const std::unordered_set &GetCCompileFlags() const { + const std::vector &GetCCompileFlags() const { const auto &t = static_cast(*this); return t.user_.c_compile_flags; } - const std::unordered_set &GetCppCompileFlags() const { + const std::vector &GetCppCompileFlags() const { const auto &t = static_cast(*this); return t.user_.cpp_compile_flags; } - const std::unordered_set &GetLinkFlags() const { + const std::vector &GetLinkFlags() const { const auto &t = static_cast(*this); return t.user_.link_flags; } diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h index 4929bc5e..d71f82c5 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h @@ -42,13 +42,12 @@ namespace buildcc { * Example: [Linux] "absolute_path_1:absolute_path_2:..."
*/ struct ToolchainFindConfig { - ToolchainFindConfig( - const std::unordered_set &env_vars = {"PATH"}, - const fs_unordered_set &absolute_search_paths = {}) + ToolchainFindConfig(const std::vector &env_vars = {"PATH"}, + const std::vector &absolute_search_paths = {}) : env_vars(env_vars), absolute_search_paths(absolute_search_paths) {} - std::unordered_set env_vars; - fs_unordered_set absolute_search_paths; + std::vector env_vars; + std::vector absolute_search_paths; }; template class ToolchainFind { diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 9d5361b8..71e38e0e 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -72,14 +72,14 @@ class Toolchain : public internal::FlagApi, private: struct UserSchema { - std::unordered_set preprocessor_flags; - std::unordered_set common_compile_flags; - std::unordered_set pch_compile_flags; - std::unordered_set pch_object_flags; - std::unordered_set asm_compile_flags; - std::unordered_set c_compile_flags; - std::unordered_set cpp_compile_flags; - std::unordered_set link_flags; + std::vector preprocessor_flags; + std::vector common_compile_flags; + std::vector pch_compile_flags; + std::vector pch_object_flags; + std::vector asm_compile_flags; + std::vector c_compile_flags; + std::vector cpp_compile_flags; + std::vector link_flags; }; private: diff --git a/buildcc/lib/toolchain/src/api/toolchain_find.cpp b/buildcc/lib/toolchain/src/api/toolchain_find.cpp index bdef49b3..9c1e621e 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_find.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_find.cpp @@ -68,12 +68,13 @@ ToolchainFind::Find(const ToolchainFindConfig &config) const { // Initialization const T &t = static_cast(*this); std::vector found_toolchains; - fs_unordered_set absolute_search_paths(config.absolute_search_paths); + std::vector absolute_search_paths(config.absolute_search_paths); // Parse config envs and add it to absolute search paths - for (const std::string &env_var : config.env_vars) { + for (const auto &env_var : config.env_vars) { std::vector paths = ParseEnvVarToPaths(env_var); - absolute_search_paths.insert(paths.begin(), paths.end()); + absolute_search_paths.insert(absolute_search_paths.end(), paths.begin(), + paths.end()); } // Over the absolute search paths diff --git a/buildcc/lib/toolchain/test/test_toolchain_find.cpp b/buildcc/lib/toolchain/test/test_toolchain_find.cpp index 9b67961a..9657dfb9 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_find.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_find.cpp @@ -40,7 +40,7 @@ TEST(ToolchainFindTestGroup, FindToolchain_ThroughEnvVar) { buildcc::ToolchainFindConfig config; config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); std::vector found_toolchains = gcc.Find(config); CHECK_TRUE(!found_toolchains.empty()); @@ -52,8 +52,8 @@ TEST(ToolchainFindTestGroup, FindToolchain_ThroughAbsolutePath) { buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); buildcc::ToolchainFindConfig config; - config.absolute_search_paths.insert(fs::current_path() / "toolchains" / - "gcc"); + config.absolute_search_paths.push_back(fs::current_path() / "toolchains" / + "gcc"); config.env_vars.clear(); std::vector found_toolchains = gcc.Find(config); @@ -66,8 +66,8 @@ TEST(ToolchainFindTestGroup, FindToolchain_DirectoryDoesntExist) { buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); buildcc::ToolchainFindConfig config; - config.absolute_search_paths.insert(fs::current_path() / "toolchains" / - "directory_doesnt_exist"); + config.absolute_search_paths.push_back(fs::current_path() / "toolchains" / + "directory_doesnt_exist"); config.env_vars.clear(); std::vector found_toolchains = gcc.Find(config); @@ -80,8 +80,8 @@ TEST(ToolchainFindTestGroup, FindToolchain_NoDirectoryFound) { buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); buildcc::ToolchainFindConfig config; - config.absolute_search_paths.insert(fs::current_path() / "toolchains" / - "gcc" / "ar"); + config.absolute_search_paths.push_back(fs::current_path() / "toolchains" / + "gcc" / "ar"); config.env_vars.clear(); std::vector found_toolchains = gcc.Find(config); @@ -94,7 +94,7 @@ TEST(ToolchainFindTestGroup, FindToolchain_NoToolchainFound) { buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", "ld")); buildcc::ToolchainFindConfig config; - config.absolute_search_paths.insert(fs::current_path() / "toolchains"); + config.absolute_search_paths.push_back(fs::current_path() / "toolchains"); config.env_vars.clear(); std::vector found_toolchains = gcc.Find(config); diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 96d00d6a..697fb45c 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -51,7 +51,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_BaseToolchain_Failure) { buildcc::ToolchainFindConfig config; config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); CHECK_THROWS(std::exception, gcc.Verify(config)); } @@ -61,7 +61,8 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadAbsolutePath) { buildcc::ToolchainFindConfig config; config.env_vars.clear(); - config.absolute_search_paths.insert((fs::current_path() / "does_not_exist")); + config.absolute_search_paths.push_back( + (fs::current_path() / "does_not_exist")); CHECK_THROWS(std::exception, gcc.Verify(config)); } @@ -71,7 +72,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_PathContainsDir) { buildcc::ToolchainFindConfig config; config.env_vars.clear(); - config.absolute_search_paths.insert((fs::current_path() / "toolchains")); + config.absolute_search_paths.push_back((fs::current_path() / "toolchains")); CHECK_THROWS(std::exception, gcc.Verify(config)); } @@ -90,7 +91,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_LockedFolder) { buildcc::ToolchainFindConfig config; config.env_vars.clear(); - config.absolute_search_paths.insert( + config.absolute_search_paths.push_back( (fs::current_path() / "toolchains" / "gcc")); CHECK_THROWS(std::exception, gcc.Verify(config)); @@ -129,7 +130,7 @@ TEST(ToolchainVerifyTestGroup, CustomToolchainInfo) { buildcc::ToolchainFindConfig config; config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); mock().expectOneCall("SetToolchainInfoCb"); auto info = toolchain.Verify(config); diff --git a/buildcc/schema/cmake/schema.cmake b/buildcc/schema/cmake/schema.cmake index a7703233..cfe1e0e0 100644 --- a/buildcc/schema/cmake/schema.cmake +++ b/buildcc/schema/cmake/schema.cmake @@ -31,6 +31,11 @@ if (${TESTING}) target_link_options(mock_schema PUBLIC ${TEST_LINK_FLAGS} ${BUILD_LINK_FLAGS}) # Tests + add_executable(test_path_schema + test/test_path_schema.cpp + ) + target_link_libraries(test_path_schema PRIVATE mock_schema) + add_executable(test_custom_generator_serialization test/test_custom_generator_serialization.cpp ) @@ -41,6 +46,9 @@ if (${TESTING}) ) target_link_libraries(test_target_serialization PRIVATE mock_schema) + add_test(NAME test_path_schema COMMAND test_path_schema + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test + ) add_test(NAME test_custom_generator_serialization COMMAND test_custom_generator_serialization WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test ) diff --git a/buildcc/schema/include/schema/path.h b/buildcc/schema/include/schema/path.h index 9e1107d3..0c07863f 100644 --- a/buildcc/schema/include/schema/path.h +++ b/buildcc/schema/include/schema/path.h @@ -34,63 +34,17 @@ using json = nlohmann::ordered_json; namespace buildcc::internal { -// TODO, Update this -struct Path { +struct PathInfo { private: - static constexpr const char *const kPathName = "path"; - static constexpr const char *const kHashName = "hash"; + static constexpr const char *const kPath = "path"; + static constexpr const char *const kHash = "hash"; public: - Path() = default; - Path(const fs::path &path, std::uint64_t timestamp = 0) - : pathname(path), last_write_timestamp(timestamp) { - pathname.lexically_normal().make_preferred(); - } - - /** - * @brief Create a Existing Path object and sets last_write_timstamp to file - * timestamp - * NOTE, Throws buildcc::env::assert_exception if file not found - * - * @param pathname - * @return Path - */ - static Path CreateExistingPath(const fs::path &pathname) { - std::error_code errcode; - uint64_t last_write_timestamp = - std::filesystem::last_write_time(pathname, errcode) - .time_since_epoch() - .count(); - env::assert_fatal(errcode.value() == 0, - fmt::format("{} not found", pathname)); + PathInfo() = default; + PathInfo(const std::string &p, const std::string &h) : path(p), hash(h) {} - return Path(pathname, last_write_timestamp); - } - - /** - * @brief Get fs::path as std::string while keeping the preferred os - * path delimiters - * '\\' for windows and '/' for linux - * - * @return std::string - */ - std::string GetPathAsString() const { return pathname.string(); } - - /** - * @brief Get fs::path as std::string for display - * Converts '\\' to '/' for conformity - * - * @return std::string - */ - std::string GetPathAsStringForDisplay() const { - return Quote(ConvertPathToString()); - } - - // Used during find operation - bool operator==(const Path &p) const { return pathname == p.pathname; } - - bool operator==(const fs::path &other_pathname) const { - return pathname == other_pathname; + bool operator==(const PathInfo &other) const { + return ((path == other.path) && (hash == other.hash)); } /** @@ -101,11 +55,8 @@ struct Path { * @param str User provided fs::path/std::string * @return std::string Sanitized path as std::string */ - static std::string ToPathString(const std::string &str) { - auto path_str = str; - std::replace(path_str.begin(), path_str.end(), '\\', '/'); - path_str = fs::path(path_str).lexically_normal().string(); - return path_str; + static std::string ToPathString(const fs::path &p) { + return fs::path(p).make_preferred().lexically_normal().string(); } /** @@ -121,8 +72,8 @@ struct Path { * @param str User provided fs::path/std::string * @return std::string Sanitized path as std::string for display */ - static std::string ToPathDisplayString(const std::string &str) { - auto path_str = ToPathString(str); + static std::string ToPathDisplayString(const fs::path &p) { + auto path_str = ToPathString(p); // if spaces are present in the path string, surround this with brackets if (path_str.find(' ') != std::string::npos) { path_str = fmt::format("\"{}\"", path_str); @@ -130,51 +81,20 @@ struct Path { return path_str; } - // JSON specialization - - friend void to_json(json &j, const Path &p) { - j[kPathName] = p.pathname; - j[kHashName] = p.last_write_timestamp; + friend void to_json(json &j, const PathInfo &info) { + j[kPath] = info.path; + j[kHash] = info.hash; } - friend void from_json(const json &j, Path &p) { - j.at(kPathName).get_to(p.pathname); - j.at(kHashName).get_to(p.last_write_timestamp); + friend void from_json(const json &j, PathInfo &info) { + j.at(kPath).get_to(info.path); + j.at(kHash).get_to(info.hash); } -private: - std::string Quote(const std::string &str) const { - if (str.find(" ") == std::string::npos) { - return str; - } - return fmt::format("\"{}\"", str); - } - - std::string ConvertPathToString() const { - std::string pstr = pathname.string(); - std::replace(pstr.begin(), pstr.end(), '\\', '/'); - return pstr; - } - -public: - fs::path pathname; - // TODO, Change this to std::string hash - std::uint64_t last_write_timestamp{0}; + std::string path; + std::string hash; }; -// TODO, Remove this -// Used by Path -class PathHash { -public: - size_t operator()(const Path &p) const { return fs::hash_value(p.pathname); } - - size_t operator()(const fs::path &p) const { return fs::hash_value(p); } -}; - -// TODO, Remove this -using path_unordered_set = std::unordered_set; -using fs_unordered_set = std::unordered_set; - /** * @brief Stores path */ @@ -187,13 +107,31 @@ class PathList { } } - void Emplace(const std::string &pstr) { - auto path_str = Path::ToPathString(pstr); - paths_.emplace(std::move(path_str)); + void Emplace(const fs::path &p) { + auto path_str = PathInfo::ToPathString(p); + paths_.emplace_back(std::move(path_str)); + } + + // TODO, Create a move version of Emplace(std::string &&pstr) + + void Insert(const PathList &other) { + paths_.insert(paths_.end(), other.paths_.begin(), other.paths_.end()); } + // TODO, Create a move version of Insert (PathList &&) + + // TODO, Remove this (redundant, use operator == overload instead) bool IsEqual(const PathList &other) const { return paths_ == other.paths_; } - const std::unordered_set &GetPaths() const { return paths_; } + + const std::vector &GetPaths() const { return paths_; } + + std::unordered_set GetUnorderedPaths() const { + std::unordered_set unordered_paths(paths_.begin(), + paths_.end()); + return unordered_paths; + } + + bool operator==(const PathList &other) const { return IsEqual(other); } friend void to_json(json &j, const PathList &plist) { j = plist.paths_; } @@ -202,7 +140,7 @@ class PathList { } private: - std::unordered_set paths_; + std::vector paths_; }; /** @@ -210,10 +148,6 @@ class PathList { * */ class PathInfoList { -private: - static constexpr const char *const kPath = "path"; - static constexpr const char *const kHash = "hash"; - public: PathInfoList() = default; explicit PathInfoList( @@ -224,43 +158,52 @@ class PathInfoList { } } - void Emplace(const std::string &pstr, const std::string &hash) { - auto path_str = Path::ToPathString(pstr); - path_infos_.emplace(std::move(path_str), hash); + void Emplace(const fs::path &p, const std::string &hash) { + auto path_str = PathInfo::ToPathString(p); + infos_.emplace_back(PathInfo(path_str, hash)); } - void ComputeHashForAll() { - for (auto &[path_str, hash] : path_infos_) { - hash = ComputeHash(path_str); - } + // TODO, Create a move version of Emplace(std::string &&pstr, std::string + // &&hash) + + void Insert(const PathInfoList &other) { + infos_.insert(infos_.end(), other.infos_.begin(), other.infos_.end()); } - const std::string &GetHash(const std::string &str) const { - auto path_str = Path::ToPathString(str); - const bool found = path_infos_.find(path_str) != path_infos_.end(); - env::assert_fatal(found, ""); - return path_infos_.at(path_str); + // TODO, Create a move version of Insert(PathInfoList &&other) + + void ComputeHashForAll() { + for (auto &info : infos_) { + info.hash = ComputeHash(info.path); + } } + // TODO, Remove redundant function (use operator == overload) bool IsEqual(const PathInfoList &other) const { - return path_infos_ == other.path_infos_; + return infos_ == other.infos_; } - const std::unordered_map &GetPathInfos() const { - return path_infos_; + const std::vector &GetPathInfos() const { return infos_; } + + std::unordered_map GetUnorderedPathInfos() const { + std::unordered_map unordered_path_infos; + for (const auto &info : infos_) { + unordered_path_infos.try_emplace(info.path, info.hash); + } + return unordered_path_infos; } - std::unordered_set GetPaths() const { - std::unordered_set paths; - for (const auto &[path_str, hash] : path_infos_) { - paths.emplace(path_str); + std::vector GetPaths() const { + std::vector paths; + for (const auto &info : infos_) { + paths.emplace_back(info.path); } return paths; } // TODO, Add Compute Strategy enum static std::string ComputeHash(const std::string &pstr) { - auto path_str = Path::ToPathString(pstr); + auto path_str = PathInfo::ToPathString(pstr); // TODO, There might be a file checksum hash compute strategy // This is the timestamp hash compute strategy @@ -274,70 +217,34 @@ class PathInfoList { return std::to_string(last_write_timestamp); } - friend void to_json(json &j, const PathInfoList &plist) { - j = plist.path_infos_; - } + bool operator==(const PathInfoList &other) const { return IsEqual(other); } + + friend void to_json(json &j, const PathInfoList &plist) { j = plist.infos_; } friend void from_json(const json &j, PathInfoList &plist) { - j.get_to(plist.path_infos_); + j.get_to(plist.infos_); } private: - std::unordered_map path_infos_; + std::vector infos_; }; -// TODO, Remove this -inline std::vector -path_schema_convert(const std::vector &path_list, - const std::function &cb = - Path::CreateExistingPath) { - std::vector internal_path_list; - for (const auto &p : path_list) { - internal_path_list.push_back(cb(p)); - } - return internal_path_list; -} - -// TODO, Remove this -inline path_unordered_set -path_schema_convert(const fs_unordered_set &path_set, - const std::function &cb = - Path::CreateExistingPath) { - path_unordered_set internal_path_set; - for (const auto &p : path_set) { - internal_path_set.insert(cb(p)); - } - return internal_path_set; -} - -// TODO, Remove this -inline fs_unordered_set -path_schema_convert(const path_unordered_set &internal_path_set) { - fs_unordered_set path_set; - for (const auto &p : internal_path_set) { - path_set.insert(p.pathname); - } - return path_set; -} - } // namespace buildcc::internal namespace buildcc { inline std::string path_as_string(const fs::path &p) { - return internal::Path(p).GetPathAsString(); + return internal::PathInfo::ToPathString(p); } inline std::string path_as_display_string(const fs::path &p) { - return internal::Path(p).GetPathAsStringForDisplay(); + return internal::PathInfo::ToPathDisplayString(p); } -inline fs::path string_as_path(const std::string &str) { - return internal::Path(str).pathname; +inline fs::path string_as_path(const std::string &p) { + return path_as_string(p); } -using fs_unordered_set = internal::fs_unordered_set; - } // namespace buildcc // FMT specialization diff --git a/buildcc/schema/include/schema/target_schema.h b/buildcc/schema/include/schema/target_schema.h index f1cae3f0..474bcb86 100644 --- a/buildcc/schema/include/schema/target_schema.h +++ b/buildcc/schema/include/schema/target_schema.h @@ -29,27 +29,29 @@ struct TargetSchema { std::string name; TargetType type{TargetType::Undefined}; - path_unordered_set internal_sources; - path_unordered_set internal_headers; - path_unordered_set internal_pchs; - std::vector internal_libs; + PathInfoList sources; + PathInfoList headers; + PathInfoList pchs; + + PathInfoList libs; std::vector external_libs; - fs_unordered_set include_dirs; - fs_unordered_set lib_dirs; + PathList include_dirs; + PathList lib_dirs; - std::unordered_set preprocessor_flags; - std::unordered_set common_compile_flags; - std::unordered_set pch_compile_flags; - std::unordered_set pch_object_flags; - std::unordered_set asm_compile_flags; - std::unordered_set c_compile_flags; - std::unordered_set cpp_compile_flags; - std::unordered_set link_flags; + std::vector preprocessor_flags; + std::vector common_compile_flags; + std::vector pch_compile_flags; + std::vector pch_object_flags; + std::vector asm_compile_flags; + std::vector c_compile_flags; + std::vector cpp_compile_flags; + std::vector link_flags; - path_unordered_set internal_compile_dependencies; - path_unordered_set internal_link_dependencies; + PathInfoList compile_dependencies; + PathInfoList link_dependencies; + // TODO, Verify this using fs::exists bool pch_compiled{false}; bool target_linked{false}; @@ -87,10 +89,10 @@ struct TargetSchema { friend void to_json(json &j, const TargetSchema &schema) { j[kName] = schema.name; j[kType] = schema.type; - j[kSources] = schema.internal_sources; - j[kHeaders] = schema.internal_headers; - j[kPchs] = schema.internal_pchs; - j[kLibs] = schema.internal_libs; + j[kSources] = schema.sources; + j[kHeaders] = schema.headers; + j[kPchs] = schema.pchs; + j[kLibs] = schema.libs; j[kExternalLibs] = schema.external_libs; j[kIncludeDirs] = schema.include_dirs; j[kLibDirs] = schema.lib_dirs; @@ -104,8 +106,8 @@ struct TargetSchema { j[kCppCompileFlags] = schema.cpp_compile_flags; j[kLinkFlags] = schema.link_flags; - j[kCompileDependencies] = schema.internal_compile_dependencies; - j[kLinkDependencies] = schema.internal_link_dependencies; + j[kCompileDependencies] = schema.compile_dependencies; + j[kLinkDependencies] = schema.link_dependencies; j[kPchCompiled] = schema.pch_compiled; j[kTargetLinked] = schema.target_linked; } @@ -113,10 +115,10 @@ struct TargetSchema { friend void from_json(const json &j, TargetSchema &schema) { j.at(kName).get_to(schema.name); j.at(kType).get_to(schema.type); - j.at(kSources).get_to(schema.internal_sources); - j.at(kHeaders).get_to(schema.internal_headers); - j.at(kPchs).get_to(schema.internal_pchs); - j.at(kLibs).get_to(schema.internal_libs); + j.at(kSources).get_to(schema.sources); + j.at(kHeaders).get_to(schema.headers); + j.at(kPchs).get_to(schema.pchs); + j.at(kLibs).get_to(schema.libs); j.at(kExternalLibs).get_to(schema.external_libs); j.at(kIncludeDirs).get_to(schema.include_dirs); j.at(kLibDirs).get_to(schema.lib_dirs); @@ -130,8 +132,8 @@ struct TargetSchema { j.at(kCppCompileFlags).get_to(schema.cpp_compile_flags); j.at(kLinkFlags).get_to(schema.link_flags); - j.at(kCompileDependencies).get_to(schema.internal_compile_dependencies); - j.at(kLinkDependencies).get_to(schema.internal_link_dependencies); + j.at(kCompileDependencies).get_to(schema.compile_dependencies); + j.at(kLinkDependencies).get_to(schema.link_dependencies); j.at(kPchCompiled).get_to(schema.pch_compiled); j.at(kTargetLinked).get_to(schema.target_linked); } diff --git a/buildcc/schema/include/schema/target_serialization.h b/buildcc/schema/include/schema/target_serialization.h index bc5116a3..f8cc532b 100644 --- a/buildcc/schema/include/schema/target_serialization.h +++ b/buildcc/schema/include/schema/target_serialization.h @@ -33,7 +33,7 @@ class TargetSerialization : public SerializationInterface { void UpdatePchCompiled(const TargetSchema &store); void UpdateTargetCompiled(); - void AddSource(const internal::Path &source); + void AddSource(const std::string &source, const std::string &hash); void UpdateStore(const TargetSchema &store); const TargetSchema &GetLoad() const { return load_; } diff --git a/buildcc/schema/src/target_serialization.cpp b/buildcc/schema/src/target_serialization.cpp index 9e447893..55826069 100644 --- a/buildcc/schema/src/target_serialization.cpp +++ b/buildcc/schema/src/target_serialization.cpp @@ -20,13 +20,15 @@ namespace buildcc::internal { // PUBLIC void TargetSerialization::UpdatePchCompiled(const TargetSchema &store) { - store_.internal_pchs = store.internal_pchs; + store_.pchs = store.pchs; store_.pch_compiled = true; } -void TargetSerialization::AddSource(const internal::Path &source) { +// TODO, When you add source here you need to add it with the hash +void TargetSerialization::AddSource(const std::string &source, + const std::string &hash) { std::scoped_lock guard(add_source_mutex); - store_.internal_sources.insert(source); + store_.sources.Emplace(source, hash); } void TargetSerialization::UpdateTargetCompiled() { @@ -35,9 +37,9 @@ void TargetSerialization::UpdateTargetCompiled() { void TargetSerialization::UpdateStore(const TargetSchema &store) { TargetSchema temp = store; - temp.internal_pchs = store_.internal_pchs; + temp.pchs = store_.pchs; temp.pch_compiled = store_.pch_compiled; - temp.internal_sources = store_.internal_sources; + temp.sources = store_.sources; temp.target_linked = store_.target_linked; store_ = std::move(temp); } diff --git a/buildcc/schema/test/test_path_schema.cpp b/buildcc/schema/test/test_path_schema.cpp new file mode 100644 index 00000000..fe5543b2 --- /dev/null +++ b/buildcc/schema/test/test_path_schema.cpp @@ -0,0 +1,147 @@ +// Internal +#include "schema/path.h" + +#include "env/host_os.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" + +// clang-format off +TEST_GROUP(PathSchemaTestGroup) +{ +}; +// clang-format on + +TEST(PathSchemaTestGroup, PathList) { buildcc::internal::PathList paths; } + +TEST(PathSchemaTestGroup, Path_ToPathString) { + auto path_str = + buildcc::internal::PathInfo::ToPathString("hello/\\first.txt"); + + if constexpr (buildcc::env::is_win()) { + STRCMP_EQUAL("hello\\first.txt", path_str.c_str()); + } else if constexpr (buildcc::env::is_linux() || buildcc::env::is_mac() || + buildcc::env::is_unix()) { + STRCMP_EQUAL("hello/\\first.txt", path_str.c_str()); + } else { + FAIL("Operating system not supported"); + } +} + +TEST(PathSchemaTestGroup, Path_ToPathDisplayString) { + auto path_str = buildcc::internal::PathInfo::ToPathDisplayString( + "hello/\\first/hello world.txt"); + + if constexpr (buildcc::env::is_win()) { + STRCMP_EQUAL("\"hello\\first\\hello world.txt\"", path_str.c_str()); + } else if constexpr (buildcc::env::is_linux() || buildcc::env::is_mac() || + buildcc::env::is_unix()) { + STRCMP_EQUAL("\"hello/\\first/hello world.txt\"", path_str.c_str()); + } else { + FAIL("Operating system not supported"); + } +} + +TEST(PathSchemaTestGroup, PathInfoList_OrderedEmplace) { + buildcc::internal::PathInfoList path_infos; + + path_infos.Emplace("hello/world/first_file.txt", ""); + path_infos.Emplace("hello/world/second_file.txt", ""); + path_infos.Emplace("hello/world/third_file.txt", ""); + path_infos.Emplace("hello/world/fourth_file.txt", ""); + + std::vector paths; + if constexpr (buildcc::env::is_win()) { + paths = { + "hello\\world\\first_file.txt", + "hello\\world\\second_file.txt", + "hello\\world\\third_file.txt", + "hello\\world\\fourth_file.txt", + }; + } else if constexpr (buildcc::env::is_linux() || buildcc::env::is_unix() || + buildcc::env::is_mac()) { + paths = { + "hello/world/first_file.txt", + "hello/world/second_file.txt", + "hello/world/third_file.txt", + "hello/world/fourth_file.txt", + }; + } else { + FAIL("Operating system not supported"); + } + + auto inserted_paths = path_infos.GetPaths(); + for (std::size_t i = 0; i < inserted_paths.size(); i++) { + STRCMP_EQUAL(paths[i].c_str(), inserted_paths[i].c_str()); + } + + json j = path_infos; + UT_PRINT(j.dump().c_str()); +} + +TEST(PathSchemaTestGroup, PathInfoList_GetChanged) { + { + buildcc::internal::PathInfoList pinfolist1{ + {"first.txt", "1"}, + {"second.txt", "2"}, + {"third.txt", "3"}, + }; + buildcc::internal::PathInfoList pinfolist2{ + {"first.txt", "1"}, + {"second.txt", "2"}, + {"third.txt", "3"}, + }; + CHECK_TRUE(pinfolist1.IsEqual(pinfolist2)); + } + + // Missing path info + { + buildcc::internal::PathInfoList pinfolist1{ + {"first.txt", "1"}, + {"second.txt", "2"}, + {"third.txt", "3"}, + }; + buildcc::internal::PathInfoList pinfolist2{ + {"first.txt", "1"}, {"second.txt", "2"}, + // {"third.txt", "3"}, + }; + CHECK_FALSE(pinfolist1.IsEqual(pinfolist2)); + } + + // Wrong hash + { + buildcc::internal::PathInfoList pinfolist1{ + {"first.txt", "1"}, + {"second.txt", "2"}, + {"third.txt", "3"}, + }; + buildcc::internal::PathInfoList pinfolist2{ + {"first.txt", "1"}, + {"second.txt", "2"}, + {"third.txt", "4"}, + }; + CHECK_FALSE(pinfolist1.IsEqual(pinfolist2)); + } + + // Wrong order + { + buildcc::internal::PathInfoList pinfolist1{ + {"first.txt", "1"}, + {"second.txt", "2"}, + {"third.txt", "3"}, + }; + buildcc::internal::PathInfoList pinfolist2{ + {"first.txt", "1"}, + {"third.txt", "3"}, + {"second.txt", "2"}, + }; + CHECK_FALSE(pinfolist1.IsEqual(pinfolist2)); + } +} + +int main(int ac, char **av) { + return CommandLineTestRunner::RunAllTests(ac, av); +} diff --git a/buildcc/toolchains/test/test_toolchain_specialized.cpp b/buildcc/toolchains/test/test_toolchain_specialized.cpp index bb316ec5..0678875e 100644 --- a/buildcc/toolchains/test/test_toolchain_specialized.cpp +++ b/buildcc/toolchains/test/test_toolchain_specialized.cpp @@ -37,7 +37,7 @@ TEST(ToolchainSpecializedTestGroup, GCC) { fs::path current_directory = fs::current_path(); buildcc::ToolchainFindConfig find_config; find_config.env_vars.clear(); - find_config.absolute_search_paths.insert(current_directory); + find_config.absolute_search_paths.push_back(current_directory); std::vector version_stdout{"version"}; std::vector arch_stdout{"arch"}; @@ -60,7 +60,7 @@ TEST(ToolchainSpecializedTestGroup, GCC_Fail) { fs::path current_directory = fs::current_path(); buildcc::ToolchainFindConfig find_config; find_config.env_vars.clear(); - find_config.absolute_search_paths.insert(current_directory); + find_config.absolute_search_paths.push_back(current_directory); { std::vector version_stdout{"version"}; @@ -107,7 +107,7 @@ TEST(ToolchainSpecializedTestGroup, MINGW) { fs::path current_directory = fs::current_path(); buildcc::ToolchainFindConfig find_config; find_config.env_vars.clear(); - find_config.absolute_search_paths.insert(current_directory); + find_config.absolute_search_paths.push_back(current_directory); std::vector version_stdout{"version"}; std::vector arch_stdout{"arch"}; @@ -139,7 +139,7 @@ TEST(ToolchainSpecializedTestGroup, MSVC) { fs::path current_directory = fs::current_path(); buildcc::ToolchainFindConfig find_config; find_config.env_vars.clear(); - find_config.absolute_search_paths.insert(current_directory); + find_config.absolute_search_paths.push_back(current_directory); char vscmd_ver[] = "VSCMD_VER=version"; char vscmd_arg_host_arch[] = "VSCMD_ARG_HOST_ARCH=host"; @@ -171,7 +171,7 @@ TEST(ToolchainSpecializedTestGroup, MSVC_Fail) { fs::path current_directory = fs::current_path(); buildcc::ToolchainFindConfig find_config; find_config.env_vars.clear(); - find_config.absolute_search_paths.insert(current_directory); + find_config.absolute_search_paths.push_back(current_directory); { char vscmd_ver[] = "VSCMD_VER"; @@ -231,7 +231,7 @@ TEST(ToolchainSpecializedTestGroup, Clang) { fs::path current_directory = fs::current_path(); buildcc::ToolchainFindConfig find_config; find_config.env_vars.clear(); - find_config.absolute_search_paths.insert(current_directory); + find_config.absolute_search_paths.push_back(current_directory); std::vector version_stdout{"version"}; std::vector arch_stdout{"arch"};

>bLU1nD5Kt*X9A;Wt$|=~eabp>- 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 e|ND#kxZGsUY6bBC literal 126774 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