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 --------------------