From 372b03ebfea1138bc9971050e7ce44c0461c6944 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 24 Apr 2022 23:31:42 -0700 Subject: [PATCH 01/38] Updated storage.h --- buildcc/lib/env/include/env/storage.h | 31 ++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/buildcc/lib/env/include/env/storage.h b/buildcc/lib/env/include/env/storage.h index ade21c3b..9d719c82 100644 --- a/buildcc/lib/env/include/env/storage.h +++ b/buildcc/lib/env/include/env/storage.h @@ -58,10 +58,12 @@ class ScopedStorage { return *ptr; } + // TODO, Remove this + // Replace above with delete ptr; template void Remove(T *ptr) { delete ptr; } 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 +79,27 @@ 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; + } + 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 { @@ -118,6 +135,14 @@ 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(); From 2f5ca64d7c72723cc3a23c2e36553c4e69db0f7e Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 25 Apr 2022 00:05:03 -0700 Subject: [PATCH 02/38] Update ScopedStorage --- buildcc/lib/env/include/env/storage.h | 7 +++---- buildcc/lib/env/test/test_storage.cpp | 22 +++++++++++++++++----- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/buildcc/lib/env/include/env/storage.h b/buildcc/lib/env/include/env/storage.h index 9d719c82..675f05b8 100644 --- a/buildcc/lib/env/include/env/storage.h +++ b/buildcc/lib/env/include/env/storage.h @@ -58,10 +58,6 @@ class ScopedStorage { return *ptr; } - // TODO, Remove this - // Replace above with delete ptr; - template void Remove(T *ptr) { delete ptr; } - template const T &ConstRef(const std::string &identifier) const { env::assert_fatal(Contains(identifier), fmt::format("Could not find '{}'", identifier)); @@ -94,6 +90,9 @@ class ScopedStorage { return true; } +protected: + template void Remove(T *ptr) { delete ptr; } + private: /** * @brief diff --git a/buildcc/lib/env/test/test_storage.cpp b/buildcc/lib/env/test/test_storage.cpp index 929fc0ba..6785a5cb 100644 --- a/buildcc/lib/env/test/test_storage.cpp +++ b/buildcc/lib/env/test/test_storage.cpp @@ -23,6 +23,14 @@ TEST_GROUP(StorageTestGroup) }; // 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 +50,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 +58,17 @@ 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")); // 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,10 +79,8 @@ 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); } From af591339a475d43f906989b52a362282fa348d54 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 25 Apr 2022 00:14:17 -0700 Subject: [PATCH 03/38] Added Clear API for ScopedStorage --- buildcc/lib/env/include/env/storage.h | 15 ++++++++------- buildcc/lib/env/test/test_storage.cpp | 6 ++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/buildcc/lib/env/include/env/storage.h b/buildcc/lib/env/include/env/storage.h index 675f05b8..1d6a57e9 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,6 +52,13 @@ class ScopedStorage { return *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(Contains(identifier), fmt::format("Could not find '{}'", identifier)); diff --git a/buildcc/lib/env/test/test_storage.cpp b/buildcc/lib/env/test/test_storage.cpp index 6785a5cb..dad775ea 100644 --- a/buildcc/lib/env/test/test_storage.cpp +++ b/buildcc/lib/env/test/test_storage.cpp @@ -64,6 +64,10 @@ TEST(ScopedStorageTestGroup, BasicUsage) { 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 } @@ -84,6 +88,8 @@ TEST(ScopedStorageTestGroup, NullptrDelete) { storage.Remove(nullptr); } +// + TEST(StorageTestGroup, BasicUsage) { buildcc::Storage::Add("identifier", "name", 10, obj); buildcc::Storage::Add("identifier2", "name2", 12, obj); From f5cd405a04b7bb960a233d988682830bc2e98861 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 25 Apr 2022 00:35:01 -0700 Subject: [PATCH 04/38] Updated static Storage API --- buildcc/lib/env/include/env/storage.h | 7 +++---- buildcc/lib/env/src/storage.cpp | 8 ++------ buildcc/lib/env/test/test_storage.cpp | 17 +++++++++-------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/buildcc/lib/env/include/env/storage.h b/buildcc/lib/env/include/env/storage.h index 1d6a57e9..21d5528e 100644 --- a/buildcc/lib/env/include/env/storage.h +++ b/buildcc/lib/env/include/env/storage.h @@ -118,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); @@ -147,7 +146,7 @@ class Storage { 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 dad775ea..4c38b134 100644 --- a/buildcc/lib/env/test/test_storage.cpp +++ b/buildcc/lib/env/test/test_storage.cpp @@ -15,10 +15,11 @@ 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 @@ -102,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) { From f36083ce8d90a53333f10710d6bb5ceac0cfe8c0 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 25 Apr 2022 00:39:01 -0700 Subject: [PATCH 05/38] Updated specialized toolchains --- buildcc/toolchains/include/toolchains/toolchain_gcc.h | 5 +++++ buildcc/toolchains/include/toolchains/toolchain_mingw.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index 9e54351f..9e277cb0 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -41,6 +41,11 @@ class Toolchain_gcc : public Toolchain { public: Toolchain_gcc() : Toolchain(ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld") {} + Toolchain_gcc(const std::string &name, const std::string &assembler, + const std::string &c_compiler, const std::string &cpp_compiler, + const std::string &archiver, const std::string &linker) + : Toolchain(ToolchainId::Gcc, name, assembler, c_compiler, cpp_compiler, + archiver, linker) {} Toolchain_gcc(const Toolchain_gcc &gcc) = delete; private: diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index d0e76824..b8bcb5c3 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -39,7 +39,7 @@ 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") {} From d7768bbcccdd6f9c1e816ce91814656212494cf6 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 25 Apr 2022 00:46:01 -0700 Subject: [PATCH 06/38] Added toolchain_generic.h --- buildcc/toolchains/CMakeLists.txt | 2 + .../include/toolchains/toolchain_generic.h | 69 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 buildcc/toolchains/include/toolchains/toolchain_generic.h diff --git a/buildcc/toolchains/CMakeLists.txt b/buildcc/toolchains/CMakeLists.txt index d7e8b6c3..13968820 100644 --- a/buildcc/toolchains/CMakeLists.txt +++ b/buildcc/toolchains/CMakeLists.txt @@ -2,6 +2,8 @@ set(TOOLCHAIN_SPECIALIZED_SRCS include/toolchains/toolchain_gcc.h include/toolchains/toolchain_msvc.h include/toolchains/toolchain_mingw.h + + include/toolchains/toolchain_generic.h ) if(${BUILDCC_BUILD_AS_SINGLE_LIB}) diff --git a/buildcc/toolchains/include/toolchains/toolchain_generic.h b/buildcc/toolchains/include/toolchains/toolchain_generic.h new file mode 100644 index 00000000..b6e9d89f --- /dev/null +++ b/buildcc/toolchains/include/toolchains/toolchain_generic.h @@ -0,0 +1,69 @@ +/* + * 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: + template + static Toolchain &New(const std::string &identifier, Params &&...params) { + Toolchain *toolchain{nullptr}; + + if constexpr (id == ToolchainId::Gcc) { + toolchain = + AddIf(identifier, std::forward(params)...); + } + + if constexpr (id == ToolchainId::Msvc) { + toolchain = + AddIf(identifier, std::forward(params)...); + } + + if constexpr (id == ToolchainId::MinGW) { + toolchain = + AddIf(identifier, std::forward(params)...); + } + + 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 From 9f0580c63d004beb7ad00b5b9721d5c6896d944a Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 25 Apr 2022 00:47:31 -0700 Subject: [PATCH 07/38] Updated register.cpp with SystemInit --- buildcc/lib/args/src/register.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) 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(); } } From bfbf8d50a096a38bfdcaa51b35a02f9a197c101d Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 25 Apr 2022 21:12:22 -0700 Subject: [PATCH 08/38] Updated toolchain verify --- .../include/toolchain/api/toolchain_verify.h | 24 +-- .../toolchain/include/toolchain/toolchain.h | 5 + .../toolchain/src/api/toolchain_verify.cpp | 172 +----------------- .../lib/toolchain/src/toolchain/toolchain.cpp | 8 + 4 files changed, 15 insertions(+), 194 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index 2ebd2423..c42ad914 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -60,19 +60,7 @@ typedef std::function(const ToolchainExecut 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 @@ -86,16 +74,6 @@ template class ToolchainVerify { */ ToolchainCompilerInfo Verify(const ToolchainVerifyConfig &config = ToolchainVerifyConfig()); - -protected: - ToolchainCompilerInfo verified_toolchain_; - -private: - void Initialize(); - static const ToolchainVerificationFunc & - GetVerificationFunc(const std::string &identifier); - static std::unordered_map & - GetStatic(); }; } // namespace buildcc diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 7ae3e959..ed48e330 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 @@ -38,6 +39,7 @@ class Toolchain : public internal::FlagApi, public ToolchainVerify { public: public: + // TODO, Remove ToolchainId from here Toolchain(ToolchainId id, std::string_view name, const ToolchainExecutables &executables, bool lock = true, const ToolchainConfig &config = ToolchainConfig()) @@ -94,6 +96,9 @@ class Toolchain : public internal::FlagApi, void Initialize(); virtual void UpdateConfig(ToolchainConfig &config); + // TODO, Make this pure virtual + virtual std::optional + GetToolchainInfo(const ToolchainExecutables &executables) const; private: friend class internal::FlagApi; diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 1d60b80f..15a6c78b 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,66 +69,10 @@ 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) { @@ -215,13 +82,7 @@ ToolchainVerify::Verify(const ToolchainVerifyConfig &config) { 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"); @@ -234,37 +95,6 @@ ToolchainVerify::Verify(const ToolchainVerifyConfig &config) { 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); - } -} - -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; } // namespace buildcc diff --git a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp index 53bee71c..c87aac2e 100644 --- a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp +++ b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp @@ -25,4 +25,12 @@ void Toolchain::Lock() { lock_.Lock(); } // PRIVATE void Toolchain::UpdateConfig(ToolchainConfig &config) { (void)config; } +std::optional +Toolchain::GetToolchainInfo(const ToolchainExecutables &executables) const { + (void)executables; + env::log_critical(__FUNCTION__, + "GetToolchainInfo virtual function not implemented"); + return {}; +} + } // namespace buildcc From 2f2b46231740efc706e2cb9c64f3a4f4130e1dc1 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 25 Apr 2022 21:12:33 -0700 Subject: [PATCH 09/38] Updated test toolchain verify tests --- .../toolchain/test/test_toolchain_verify.cpp | 267 +++++------------- 1 file changed, 64 insertions(+), 203 deletions(-) diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 5854191d..8aa5fe85 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,59 @@ TEST_GROUP(ToolchainVerifyTestGroup) }; // clang-format on +class MockToolchain : public buildcc::Toolchain { +public: + MockToolchain(buildcc::ToolchainId id, const std::string &name, + const std::string &assembler, const std::string &c_compiler, + const std::string &cpp_compiler, const std::string &archiver, + const std::string &linker) + : buildcc::Toolchain(id, name, assembler, c_compiler, cpp_compiler, + archiver, linker) {} + +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::ToolchainVerifyConfig 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", "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); @@ -54,8 +103,8 @@ 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", "as", "gcc", "g++", "ar", + "ld"); std::vector version_stdout_data{"version"}; std::vector arch_stdout_data{"arch"}; @@ -78,8 +127,8 @@ 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", "as", "gcc", "g++", "ar", + "ld"); std::vector version_stdout_data; std::vector arch_stdout_data{"arch"}; @@ -102,8 +151,8 @@ 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", "as", "gcc", "g++", "ar", + "ld"); std::vector version_stdout_data{"version"}; std::vector arch_stdout_data{"arch"}; @@ -126,8 +175,8 @@ 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", "as", "gcc", "g++", "ar", + "ld"); std::vector version_stdout_data{"version"}; std::vector arch_stdout_data; @@ -149,165 +198,9 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchEmpty) { 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; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - CHECK_THROWS(std::exception, gcc.Verify(config)); -} - TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadAbsolutePath) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", + "ld"); buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); @@ -317,8 +210,8 @@ 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", "as", "gcc", "g++", "ar", + "ld"); buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); @@ -329,38 +222,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,8 +230,8 @@ 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", "as", "gcc", "g++", "ar", + "ld"); buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); From fcdb7d4ab3626f4e83d3611fdd29cd1c7d61ca20 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 25 Apr 2022 21:13:28 -0700 Subject: [PATCH 10/38] Updated specialized_toolchains to static library --- buildcc/toolchains/CMakeLists.txt | 33 ++++--- .../include/toolchains/toolchain_gcc.h | 16 +-- .../include/toolchains/toolchain_mingw.h | 16 +-- .../include/toolchains/toolchain_msvc.h | 17 +--- buildcc/toolchains/src/toolchain_gcc.cpp | 99 +++++++++++++++++++ buildcc/toolchains/src/toolchain_msvc.cpp | 75 ++++++++++++++ 6 files changed, 202 insertions(+), 54 deletions(-) create mode 100644 buildcc/toolchains/src/toolchain_gcc.cpp create mode 100644 buildcc/toolchains/src/toolchain_msvc.cpp diff --git a/buildcc/toolchains/CMakeLists.txt b/buildcc/toolchains/CMakeLists.txt index 13968820..de152a2a 100644 --- a/buildcc/toolchains/CMakeLists.txt +++ b/buildcc/toolchains/CMakeLists.txt @@ -1,8 +1,11 @@ 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 ) @@ -10,29 +13,31 @@ 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_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index 9e277cb0..551511bf 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
@@ -49,13 +43,9 @@ class Toolchain_gcc : public Toolchain { 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_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index b8bcb5c3..d1aab5cd 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
@@ -46,13 +40,9 @@ class Toolchain_mingw : public Toolchain { 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..206a03f4 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
@@ -45,13 +38,9 @@ class Toolchain_msvc : public Toolchain { 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..21819008 --- /dev/null +++ b/buildcc/toolchains/src/toolchain_gcc.cpp @@ -0,0 +1,99 @@ +/* + * 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 "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; +} + +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; +} + +} // namespace + +namespace buildcc { + +void Toolchain_gcc::UpdateConfig(ToolchainConfig &config) { + UpdateGccConfig(config); +} + +std::optional +Toolchain_gcc::GetToolchainInfo(const ToolchainExecutables &executables) const { + return GetGccToolchainInfo(executables); +} + +void Toolchain_mingw::UpdateConfig(ToolchainConfig &config) { + UpdateGccConfig(config); +} + +std::optional Toolchain_mingw::GetToolchainInfo( + const ToolchainExecutables &executables) const { + return GetGccToolchainInfo(executables); +} + +} // namespace buildcc diff --git a/buildcc/toolchains/src/toolchain_msvc.cpp b/buildcc/toolchains/src/toolchain_msvc.cpp new file mode 100644 index 00000000..a860153f --- /dev/null +++ b/buildcc/toolchains/src/toolchain_msvc.cpp @@ -0,0 +1,75 @@ +/* + * 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" + +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:"; + +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); +} + +} // 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 { + (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; +} + +} // namespace buildcc From 189279eca3bba1182593eeef3e1938f25719cd55 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 25 Apr 2022 21:38:55 -0700 Subject: [PATCH 11/38] Minor update --- buildcc/lib/toolchain/include/toolchain/toolchain.h | 1 - 1 file changed, 1 deletion(-) diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index ed48e330..52386a36 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -37,7 +37,6 @@ namespace buildcc { class Toolchain : public internal::FlagApi, public ToolchainFind, public ToolchainVerify { -public: public: // TODO, Remove ToolchainId from here Toolchain(ToolchainId id, std::string_view name, From 7f95557162c7d751365751714642837144fd1bda Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 21:34:18 -0700 Subject: [PATCH 12/38] Updated toolchain with lock false --- buildcc/lib/toolchain/include/toolchain/toolchain.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 52386a36..199b2f3b 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -40,20 +40,20 @@ class Toolchain : public internal::FlagApi, 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()) + 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; @@ -107,8 +107,8 @@ class Toolchain : public internal::FlagApi, ToolchainId id_; std::string name_; ToolchainExecutables executables_; - FunctionLock lock_; ToolchainConfig config_; + FunctionLock lock_; // UserSchema user_; From e50772994c49f32f273edfe3474fa329ffb24e08 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 22:14:44 -0700 Subject: [PATCH 13/38] Updated specialized toolchains --- .../include/toolchains/toolchain_gcc.h | 22 +++++++++++++------ .../include/toolchains/toolchain_mingw.h | 17 ++++++++++++-- .../include/toolchains/toolchain_msvc.h | 17 ++++++++++++-- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index 551511bf..3f576ce9 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -33,13 +33,21 @@ namespace buildcc { */ class Toolchain_gcc : public Toolchain { public: - Toolchain_gcc() - : Toolchain(ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld") {} - Toolchain_gcc(const std::string &name, const std::string &assembler, - const std::string &c_compiler, const std::string &cpp_compiler, - const std::string &archiver, const std::string &linker) - : Toolchain(ToolchainId::Gcc, name, assembler, c_compiler, cpp_compiler, - archiver, linker) {} + // Compile time basic constructor + Toolchain_gcc(const std::string &name = "gcc") + : Toolchain(ToolchainId::Gcc, name, "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()).get(), + op_config.value_or(ToolchainConfig()).get()) {} + Toolchain_gcc(const Toolchain_gcc &gcc) = delete; private: diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index d1aab5cd..1839be6c 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -35,8 +35,21 @@ namespace buildcc { */ class Toolchain_mingw : public Toolchain { public: - Toolchain_mingw() - : Toolchain(ToolchainId::MinGW, "gcc", "as", "gcc", "g++", "ar", "ld") {} + // Compile time basic constructor + Toolchain_mingw(const std::string &name = "gcc") + : Toolchain(ToolchainId::MinGW, name, "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()).get(), + op_config.value_or(ToolchainConfig()).get()) {} + Toolchain_mingw(const Toolchain_mingw &) = delete; private: diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index 206a03f4..55bd40dc 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -33,8 +33,21 @@ namespace buildcc { */ class Toolchain_msvc : public Toolchain { public: - Toolchain_msvc() - : Toolchain(ToolchainId::Msvc, "msvc", "cl", "cl", "cl", "lib", "link") {} + // Compile time basic constructor + Toolchain_msvc(const std::string &name = "msvc") + : Toolchain(ToolchainId::Msvc, name, "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::Gcc, name, + op_executables.value_or(ToolchainExecutables()).get(), + op_config.value_or(ToolchainConfig()).get()) {} + Toolchain_msvc(const Toolchain_msvc &gcc) = delete; private: From 4a70ed5de1a581a2293dcc402123a05cdf39f43b Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 22:14:53 -0700 Subject: [PATCH 14/38] Updated toolchain_verify --- .../toolchain/include/toolchain/api/toolchain_verify.h | 10 +--------- buildcc/lib/toolchain/src/api/toolchain_verify.cpp | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index c42ad914..1037a98f 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 @@ -54,10 +50,6 @@ struct ToolchainCompilerInfo { std::string target_arch; }; -// clang-format off -typedef std::function(const ToolchainExecutables &)> ToolchainVerificationFunc; -// clang-format on - template class ToolchainVerify { public: ToolchainVerify() = default; @@ -73,7 +65,7 @@ template class ToolchainVerify { * of them */ ToolchainCompilerInfo - Verify(const ToolchainVerifyConfig &config = ToolchainVerifyConfig()); + Verify(const ToolchainFindConfig &config = ToolchainFindConfig()); }; } // namespace buildcc diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 15a6c78b..159efdeb 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -75,7 +75,7 @@ namespace buildcc { 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"); From 86a129def86559ec449812ead42d323d8c7f2cc9 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 22:16:30 -0700 Subject: [PATCH 15/38] Updated toolchain_generic --- .../include/toolchains/toolchain_generic.h | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_generic.h b/buildcc/toolchains/include/toolchains/toolchain_generic.h index b6e9d89f..ac9ee85d 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_generic.h +++ b/buildcc/toolchains/include/toolchains/toolchain_generic.h @@ -29,29 +29,55 @@ namespace buildcc { class Toolchain_generic { public: + // Compile time template static Toolchain &New(const std::string &identifier, Params &&...params) { Toolchain *toolchain{nullptr}; if constexpr (id == ToolchainId::Gcc) { - toolchain = - AddIf(identifier, std::forward(params)...); + toolchain = AddIf(identifier, identifier, + std::forward(params)...); } if constexpr (id == ToolchainId::Msvc) { - toolchain = - AddIf(identifier, std::forward(params)...); + toolchain = AddIf(identifier, identifier, + std::forward(params)...); } if constexpr (id == ToolchainId::MinGW) { - toolchain = - AddIf(identifier, std::forward(params)...); + toolchain = AddIf(identifier, identifier, + std::forward(params)...); } env::assert_fatal(toolchain, "Toolchain could not be created"); return *toolchain; } + // Run time + 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; + } + } + private: template static Toolchain *AddIf(const std::string &identifier, Params &&...params) { From c827f44bc7d443f7cb987ca7544ded9f34f7fd33 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 23:06:32 -0700 Subject: [PATCH 16/38] Updated specialized toolchains --- .../include/toolchains/toolchain_gcc.h | 18 ++++++------------ .../include/toolchains/toolchain_mingw.h | 18 ++++++------------ .../include/toolchains/toolchain_msvc.h | 18 ++++++------------ 3 files changed, 18 insertions(+), 36 deletions(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index 3f576ce9..c13f3220 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -33,20 +33,14 @@ namespace buildcc { */ class Toolchain_gcc : public Toolchain { public: - // Compile time basic constructor - Toolchain_gcc(const std::string &name = "gcc") - : Toolchain(ToolchainId::Gcc, name, "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_gcc(const std::string &name = "gcc", + std::optional op_executables = {}, + std::optional op_config = {}) : Toolchain(ToolchainId::Gcc, name, - op_executables.value_or(ToolchainExecutables()).get(), - op_config.value_or(ToolchainConfig()).get()) {} + op_executables.value_or( + ToolchainExecutables("as", "gcc", "g++", "ar", "ld")), + op_config.value_or(ToolchainConfig())) {} Toolchain_gcc(const Toolchain_gcc &gcc) = delete; diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index 1839be6c..5767bdfd 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -35,20 +35,14 @@ namespace buildcc { */ class Toolchain_mingw : public Toolchain { public: - // Compile time basic constructor - Toolchain_mingw(const std::string &name = "gcc") - : Toolchain(ToolchainId::MinGW, name, "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_mingw(const std::string &name = "gcc", + std::optional op_executables = {}, + std::optional op_config = {}) : Toolchain(ToolchainId::MinGW, name, - op_executables.value_or(ToolchainExecutables()).get(), - op_config.value_or(ToolchainConfig()).get()) {} + op_executables.value_or( + ToolchainExecutables("as", "gcc", "g++", "ar", "ld")), + op_config.value_or(ToolchainConfig())) {} Toolchain_mingw(const Toolchain_mingw &) = delete; diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index 55bd40dc..4ad49e1d 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -33,20 +33,14 @@ namespace buildcc { */ class Toolchain_msvc : public Toolchain { public: - // Compile time basic constructor - Toolchain_msvc(const std::string &name = "msvc") - : Toolchain(ToolchainId::Msvc, name, "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_msvc(const std::string &name = "msvc", + std::optional op_executables = {}, + std::optional op_config = {}) : Toolchain(ToolchainId::Gcc, name, - op_executables.value_or(ToolchainExecutables()).get(), - op_config.value_or(ToolchainConfig()).get()) {} + op_executables.value_or( + ToolchainExecutables("cl", "cl", "cl", "lib", "link")), + op_config.value_or(ToolchainConfig())) {} Toolchain_msvc(const Toolchain_msvc &gcc) = delete; From fdb46403ef51a9468f5bbc19510a11945240bbe5 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 23:07:19 -0700 Subject: [PATCH 17/38] Updated toolchain generic --- .../toolchains/include/toolchains/toolchain_generic.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_generic.h b/buildcc/toolchains/include/toolchains/toolchain_generic.h index ac9ee85d..7edbf12d 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_generic.h +++ b/buildcc/toolchains/include/toolchains/toolchain_generic.h @@ -54,11 +54,9 @@ class Toolchain_generic { } // Run time - static Toolchain & - New(ToolchainId id, const std::string &identifier, - std::optional> - op_executables, - std::optional> op_config) { + 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: @@ -76,6 +74,8 @@ class Toolchain_generic { default: break; } + env::assert_fatal(toolchain, "Toolchain could not be created"); + return *toolchain; } private: From 8733c8d7dfc48506528cb9a3ca9ef2888cf06c89 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 23:08:20 -0700 Subject: [PATCH 18/38] Removed toolchain lock check --- buildcc/lib/target/src/target_info/target_info.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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(), From 63027d16433dd2eadd1d3403f880c551530ad9dc Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 23:08:38 -0700 Subject: [PATCH 19/38] Updated test toolchains --- .../test/target/test_toolchain_flag_api.cpp | 9 ++++++--- .../toolchain/test/test_toolchain_verify.cpp | 18 +++++++++--------- 2 files changed, 15 insertions(+), 12 deletions(-) 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/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 8aa5fe85..35f38507 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -68,7 +68,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_BaseToolchain_Failure) { 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"); @@ -92,7 +92,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"); @@ -119,7 +119,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"); @@ -143,7 +143,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"); @@ -167,7 +167,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"); @@ -191,7 +191,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchEmpty) { 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"); @@ -202,7 +202,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadAbsolutePath) { MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.absolute_search_paths.insert((fs::current_path() / "does_not_exist")); @@ -213,7 +213,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_PathContainsDir) { MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.absolute_search_paths.insert((fs::current_path() / "toolchains")); @@ -233,7 +233,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_LockedFolder) { MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.absolute_search_paths.insert( (fs::current_path() / "toolchains" / "gcc")); From 9164ff6a5406f2677ed4f18fdae73c85112ab3f9 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 23:41:27 -0700 Subject: [PATCH 20/38] Updated buildcc.h with toolchain_generic and toolchain_custom --- buildcc/buildcc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/buildcc/buildcc.h b/buildcc/buildcc.h index 227d9ce0..40768e21 100644 --- a/buildcc/buildcc.h +++ b/buildcc/buildcc.h @@ -39,6 +39,8 @@ #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" // TODO, Add more specialized toolchains here From df4576f97e226111b3ba9395f7c3240fcef99ee6 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 23:48:46 -0700 Subject: [PATCH 21/38] Added toolchain_custom.h --- .../include/toolchains/toolchain_custom.h | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 buildcc/toolchains/include/toolchains/toolchain_custom.h diff --git a/buildcc/toolchains/include/toolchains/toolchain_custom.h b/buildcc/toolchains/include/toolchains/toolchain_custom.h new file mode 100644 index 00000000..d57e5997 --- /dev/null +++ b/buildcc/toolchains/include/toolchains/toolchain_custom.h @@ -0,0 +1,54 @@ +/* + * 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 { + +typedef std::function( + const ToolchainExecutables &)> + ToolchainInfoFunc; + +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) {} + + void SetToolchainInfoFunc(const ToolchainInfoFunc &cb) { info_func_ = cb; } + +private: + std::optional + GetToolchainInfo(const ToolchainExecutables &executables) const override { + if (info_func_) { + return info_func_(executables); + } + return {}; + } + +private: + ToolchainInfoFunc info_func_; +}; + +} // namespace buildcc + +#endif From cd200cc104a52de5160b3b0bc2e97af1a0a927b9 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Tue, 26 Apr 2022 23:51:39 -0700 Subject: [PATCH 22/38] Updated toolchain_generic with comments --- .../include/toolchains/toolchain_generic.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_generic.h b/buildcc/toolchains/include/toolchains/toolchain_generic.h index 7edbf12d..a8e0677b 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_generic.h +++ b/buildcc/toolchains/include/toolchains/toolchain_generic.h @@ -29,7 +29,13 @@ namespace buildcc { class Toolchain_generic { public: - // Compile time + /** + * @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}; @@ -53,7 +59,13 @@ class Toolchain_generic { return *toolchain; } - // Run time + /** + * @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 = {}) { From c36b2fd9feff43780b935f58ae44f7d0249a04c2 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 01:12:34 -0700 Subject: [PATCH 23/38] Updated toolchain_custom --- buildcc/toolchains/include/toolchains/toolchain_custom.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_custom.h b/buildcc/toolchains/include/toolchains/toolchain_custom.h index d57e5997..3c92aa1c 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_custom.h +++ b/buildcc/toolchains/include/toolchains/toolchain_custom.h @@ -23,10 +23,6 @@ namespace buildcc { -typedef std::function( - const ToolchainExecutables &)> - ToolchainInfoFunc; - class Toolchain_custom : public Toolchain { public: Toolchain_custom(const std::string &name, From e04d1875237e0daaf9f4a861991813fbf61fb58d Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 01:12:55 -0700 Subject: [PATCH 24/38] Updated toolchain.h --- .../toolchain/include/toolchain/toolchain.h | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 199b2f3b..f60b00d5 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -33,6 +33,10 @@ namespace buildcc { +// clang-format off +typedef std::function(const ToolchainExecutables &)> ToolchainInfoFunc; +// clang-format on + // Base toolchain class class Toolchain : public internal::FlagApi, public ToolchainFind, @@ -46,10 +50,13 @@ class Toolchain : public internal::FlagApi, 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, - 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), @@ -79,6 +86,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; From 06f0a3ec97373780126ae852d3eba0c5f63b1164 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 01:13:17 -0700 Subject: [PATCH 25/38] Updated args.h (derived from Toolchain) --- buildcc/lib/args/include/args/args.h | 44 ++++++++++++---------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index a6b37f19..278f250f 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -47,35 +47,29 @@ struct ArgToolchainState { * command line * Bundled with Toolchain State */ -struct ArgToolchain { - ArgToolchain() = default; +struct ArgToolchain : public Toolchain { + 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)) {} 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 From fe7c4f03dc6e35c69cdc32197d453004de0d6b23 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 01:21:23 -0700 Subject: [PATCH 26/38] Added virtual destructor to specialized toolchains --- buildcc/toolchains/include/toolchains/toolchain_gcc.h | 1 + buildcc/toolchains/include/toolchains/toolchain_mingw.h | 1 + buildcc/toolchains/include/toolchains/toolchain_msvc.h | 1 + 3 files changed, 3 insertions(+) diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index c13f3220..57de3c5f 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -42,6 +42,7 @@ class Toolchain_gcc : public Toolchain { ToolchainExecutables("as", "gcc", "g++", "ar", "ld")), op_config.value_or(ToolchainConfig())) {} + virtual ~Toolchain_gcc() = default; Toolchain_gcc(const Toolchain_gcc &gcc) = delete; private: diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index 5767bdfd..15f03932 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -44,6 +44,7 @@ class Toolchain_mingw : public Toolchain { ToolchainExecutables("as", "gcc", "g++", "ar", "ld")), op_config.value_or(ToolchainConfig())) {} + virtual ~Toolchain_mingw() = default; Toolchain_mingw(const Toolchain_mingw &) = delete; private: diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index 4ad49e1d..35468ff4 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -42,6 +42,7 @@ class Toolchain_msvc : public Toolchain { ToolchainExecutables("cl", "cl", "cl", "lib", "link")), op_config.value_or(ToolchainConfig())) {} + virtual ~Toolchain_msvc() = default; Toolchain_msvc(const Toolchain_msvc &gcc) = delete; private: From 4dc070d66908de54695d51e21b31ab017392d11e Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 19:53:30 -0700 Subject: [PATCH 27/38] Updated toolchain_verify --- .../include/toolchain/api/toolchain_verify.h | 20 +++++++++++++++++++ .../toolchain/include/toolchain/toolchain.h | 7 ------- .../toolchain/src/api/toolchain_verify.cpp | 12 +++++++++++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index 1037a98f..9d545285 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -50,6 +50,10 @@ struct ToolchainCompilerInfo { std::string target_arch; }; +// clang-format off +typedef std::function(const ToolchainExecutables &)> ToolchainInfoFunc; +// clang-format on + template class ToolchainVerify { public: ToolchainVerify() = default; @@ -66,6 +70,22 @@ template class ToolchainVerify { */ ToolchainCompilerInfo Verify(const ToolchainFindConfig &config = ToolchainFindConfig()); + + /** + * @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: + ToolchainInfoFunc info_func_; }; } // namespace buildcc diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index f60b00d5..4c509b28 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -33,10 +33,6 @@ namespace buildcc { -// clang-format off -typedef std::function(const ToolchainExecutables &)> ToolchainInfoFunc; -// clang-format on - // Base toolchain class class Toolchain : public internal::FlagApi, public ToolchainFind, @@ -108,9 +104,6 @@ class Toolchain : public internal::FlagApi, void Initialize(); virtual void UpdateConfig(ToolchainConfig &config); - // TODO, Make this pure virtual - virtual std::optional - GetToolchainInfo(const ToolchainExecutables &executables) const; private: friend class internal::FlagApi; diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 159efdeb..0bb987c7 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -95,6 +95,18 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { return toolchain_compiler_info; } +// PRIVATE +template +std::optional ToolchainVerify::GetToolchainInfo( + const ToolchainExecutables &executables) const { + if (info_func_) { + info_func_(executables); + } + env::log_critical(__FUNCTION__, + "GetToolchainInfo virtual function not implemented"); + return {}; +} + template class ToolchainVerify; } // namespace buildcc From 12883c2ea59444f28f53dcdb0b585ebfb662096a Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 19:53:43 -0700 Subject: [PATCH 28/38] Updated toolchain.cpp --- buildcc/lib/toolchain/src/toolchain/toolchain.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp index c87aac2e..53bee71c 100644 --- a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp +++ b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp @@ -25,12 +25,4 @@ void Toolchain::Lock() { lock_.Lock(); } // PRIVATE void Toolchain::UpdateConfig(ToolchainConfig &config) { (void)config; } -std::optional -Toolchain::GetToolchainInfo(const ToolchainExecutables &executables) const { - (void)executables; - env::log_critical(__FUNCTION__, - "GetToolchainInfo virtual function not implemented"); - return {}; -} - } // namespace buildcc From 7bc54e7b1920baefae9806c1c4b911530a1c7f08 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 19:54:11 -0700 Subject: [PATCH 29/38] Updated toolchain_custom.h --- .../include/toolchains/toolchain_custom.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_custom.h b/buildcc/toolchains/include/toolchains/toolchain_custom.h index 3c92aa1c..ba0b50bb 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_custom.h +++ b/buildcc/toolchains/include/toolchains/toolchain_custom.h @@ -29,20 +29,6 @@ class Toolchain_custom : public Toolchain { const ToolchainExecutables &executables, const ToolchainConfig &config = ToolchainConfig()) : Toolchain(ToolchainId::Custom, name, executables, config) {} - - void SetToolchainInfoFunc(const ToolchainInfoFunc &cb) { info_func_ = cb; } - -private: - std::optional - GetToolchainInfo(const ToolchainExecutables &executables) const override { - if (info_func_) { - return info_func_(executables); - } - return {}; - } - -private: - ToolchainInfoFunc info_func_; }; } // namespace buildcc From 265224493339864d8a4be1c0d25ab840ca6af08b Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 19:59:57 -0700 Subject: [PATCH 30/38] Updated toolchain gcc and msvc --- buildcc/toolchains/src/toolchain_gcc.cpp | 45 ++--------------------- buildcc/toolchains/src/toolchain_msvc.cpp | 35 ++---------------- 2 files changed, 7 insertions(+), 73 deletions(-) diff --git a/buildcc/toolchains/src/toolchain_gcc.cpp b/buildcc/toolchains/src/toolchain_gcc.cpp index 21819008..a99deef0 100644 --- a/buildcc/toolchains/src/toolchain_gcc.cpp +++ b/buildcc/toolchains/src/toolchain_gcc.cpp @@ -17,6 +17,8 @@ #include "toolchains/toolchain_gcc.h" #include "toolchains/toolchain_mingw.h" +#include "toolchains/toolchain_infos.h" + #include "env/command.h" namespace { @@ -35,45 +37,6 @@ void UpdateGccConfig(buildcc::ToolchainConfig &config) { config.prefix_lib_dir = kGccPrefixLibDir; } -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; -} - } // namespace namespace buildcc { @@ -84,7 +47,7 @@ void Toolchain_gcc::UpdateConfig(ToolchainConfig &config) { std::optional Toolchain_gcc::GetToolchainInfo(const ToolchainExecutables &executables) const { - return GetGccToolchainInfo(executables); + return GlobalToolchainInfo::Get(ToolchainId::Gcc)(executables); } void Toolchain_mingw::UpdateConfig(ToolchainConfig &config) { @@ -93,7 +56,7 @@ void Toolchain_mingw::UpdateConfig(ToolchainConfig &config) { std::optional Toolchain_mingw::GetToolchainInfo( const ToolchainExecutables &executables) const { - return GetGccToolchainInfo(executables); + return GlobalToolchainInfo::Get(ToolchainId::MinGW)(executables); } } // namespace buildcc diff --git a/buildcc/toolchains/src/toolchain_msvc.cpp b/buildcc/toolchains/src/toolchain_msvc.cpp index a860153f..a6eca961 100644 --- a/buildcc/toolchains/src/toolchain_msvc.cpp +++ b/buildcc/toolchains/src/toolchain_msvc.cpp @@ -16,6 +16,8 @@ #include "toolchains/toolchain_msvc.h" +#include "toolchains/toolchain_infos.h" + namespace { constexpr const char *const kMsvcObjExt = ".obj"; @@ -24,27 +26,6 @@ constexpr const char *const kMsvcPchCompileExt = ".pch"; constexpr const char *const kMsvcPrefixIncludeDir = "/I"; constexpr const char *const kMsvcPrefixLibDir = "/LIBPATH:"; -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); -} - } // namespace namespace buildcc { @@ -59,17 +40,7 @@ void Toolchain_msvc::UpdateConfig(ToolchainConfig &config) { std::optional Toolchain_msvc::GetToolchainInfo( const ToolchainExecutables &executables) const { - (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; + return GlobalToolchainInfo::Get(ToolchainId::Msvc)(executables); } } // namespace buildcc From 634a7a0420d3454425feeca046b9872687c18b85 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 20:00:32 -0700 Subject: [PATCH 31/38] Added toolchain infos --- buildcc/toolchains/CMakeLists.txt | 3 + .../include/toolchains/toolchain_infos.h | 37 +++++ buildcc/toolchains/src/toolchain_infos.cpp | 138 ++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 buildcc/toolchains/include/toolchains/toolchain_infos.h create mode 100644 buildcc/toolchains/src/toolchain_infos.cpp diff --git a/buildcc/toolchains/CMakeLists.txt b/buildcc/toolchains/CMakeLists.txt index de152a2a..a58b9777 100644 --- a/buildcc/toolchains/CMakeLists.txt +++ b/buildcc/toolchains/CMakeLists.txt @@ -7,6 +7,9 @@ set(TOOLCHAIN_SPECIALIZED_SRCS 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}) 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/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 From 3ccd9ed0690334943423abaade9185bfa92864d1 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 20:02:05 -0700 Subject: [PATCH 32/38] Updated args --- buildcc/lib/args/include/args/args.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index 278f250f..c0937ab0 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -47,7 +47,8 @@ struct ArgToolchainState { * command line * Bundled with Toolchain State */ -struct ArgToolchain : public Toolchain { +class ArgToolchain : public Toolchain { +public: ArgToolchain() : Toolchain(ToolchainId::Undefined, "", ToolchainExecutables()){}; ArgToolchain(ToolchainId initial_id, const std::string &initial_name, @@ -65,6 +66,7 @@ struct ArgToolchain : public Toolchain { initial_cpp_compiler, initial_archiver, initial_linker)) {} +public: ArgToolchainState state; ToolchainId &id = RefId(); std::string &name = RefName(); From 532044767519660a7c2ce39f8df09464fdc2ddb3 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 20:03:23 -0700 Subject: [PATCH 33/38] Updated buildcc.h --- buildcc/buildcc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/buildcc/buildcc.h b/buildcc/buildcc.h index 40768e21..b40f5852 100644 --- a/buildcc/buildcc.h +++ b/buildcc/buildcc.h @@ -42,6 +42,8 @@ #include "toolchains/toolchain_generic.h" #include "toolchains/toolchain_custom.h" +#include "toolchains/toolchain_infos.h" + // TODO, Add more specialized toolchains here // Specialized Targets From d3a9470e6318179a1977b3f5cf09f727023336a2 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 20:04:44 -0700 Subject: [PATCH 34/38] Updated examples, bootstrap and buildexe --- bootstrap/main.buildcc.cpp | 3 ++- buildexe/buildexe.cpp | 4 ++-- buildexe/include/buildexe/args_setup.h | 4 +--- example/hybrid/custom_target/build.main.cpp | 6 +++--- example/hybrid/generic/build.cpp | 3 ++- 5 files changed, 10 insertions(+), 10 deletions(-) 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/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/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 16136287bf6a9ac420ad8ba9b26e8dd8d9df53b3 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 20:06:14 -0700 Subject: [PATCH 35/38] Updated documentation --- docs/source/examples/hybrid.rst | 3 ++- docs/source/user_api/args.rst | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) 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; } From 4bd0c9f5dbdafb6d307c45ae5d1c0109243babf6 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 27 Apr 2022 20:29:58 -0700 Subject: [PATCH 36/38] Updated toolchain_verify and tests --- .../toolchain/src/api/toolchain_verify.cpp | 5 +- .../toolchain/test/test_toolchain_verify.cpp | 66 +++++++++++++------ 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 0bb987c7..78927b65 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -99,8 +99,9 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { template std::optional ToolchainVerify::GetToolchainInfo( const ToolchainExecutables &executables) const { - if (info_func_) { - info_func_(executables); + const auto &cb = GetToolchainInfoFunc(); + if (cb) { + return cb(executables); } env::log_critical(__FUNCTION__, "GetToolchainInfo virtual function not implemented"); diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 35f38507..1d968392 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -29,11 +29,10 @@ TEST_GROUP(ToolchainVerifyTestGroup) class MockToolchain : public buildcc::Toolchain { public: MockToolchain(buildcc::ToolchainId id, const std::string &name, - const std::string &assembler, const std::string &c_compiler, - const std::string &cpp_compiler, const std::string &archiver, - const std::string &linker) - : buildcc::Toolchain(id, name, assembler, c_compiler, cpp_compiler, - archiver, linker) {} + const buildcc::ToolchainExecutables &executables = + buildcc::ToolchainExecutables("as", "gcc", "g++", "ar", + "ld")) + : buildcc::Toolchain(id, name, executables) {} private: // Example implementation @@ -76,8 +75,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_BaseToolchain_Failure) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc) { - MockToolchain 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"}; @@ -103,8 +101,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionFailure) { - MockToolchain 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"}; @@ -127,8 +124,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionFailure) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionEmpty) { - MockToolchain 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"}; @@ -151,8 +147,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionEmpty) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchFailure) { - MockToolchain 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"}; @@ -175,8 +170,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchFailure) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchEmpty) { - MockToolchain 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; @@ -199,8 +193,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchEmpty) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadAbsolutePath) { - MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", - "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); buildcc::ToolchainFindConfig config; config.env_vars.clear(); @@ -210,8 +203,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadAbsolutePath) { } TEST(ToolchainVerifyTestGroup, VerifyToolchain_PathContainsDir) { - MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", - "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); buildcc::ToolchainFindConfig config; config.env_vars.clear(); @@ -230,8 +222,7 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_LockedFolder) { FAIL_TEST("Could not set file permissions"); } - MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", - "ld"); + MockToolchain gcc(buildcc::ToolchainId::Gcc, "gcc"); buildcc::ToolchainFindConfig config; config.env_vars.clear(); @@ -249,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); From 2da54f7b8289292a583768eec293c210a461b146 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 28 Apr 2022 01:43:27 -0700 Subject: [PATCH 37/38] Updated bootstrap for buildcc --- bootstrap/src/build_buildcc.cpp | 1 + 1 file changed, 1 insertion(+) 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"); From 2a18e45f31e5c3808ebb816fc97cf1f0210593f6 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 28 Apr 2022 02:04:45 -0700 Subject: [PATCH 38/38] Updated toolchain msvc --- buildcc/toolchains/include/toolchains/toolchain_msvc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index 35468ff4..1cfb6252 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -37,7 +37,7 @@ class Toolchain_msvc : public Toolchain { Toolchain_msvc(const std::string &name = "msvc", std::optional op_executables = {}, std::optional op_config = {}) - : Toolchain(ToolchainId::Gcc, name, + : Toolchain(ToolchainId::Msvc, name, op_executables.value_or( ToolchainExecutables("cl", "cl", "cl", "lib", "link")), op_config.value_or(ToolchainConfig())) {}