From ea827b130e7f5bcb6cf46e089f5db05576be64ed Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Fri, 18 Mar 2022 00:52:58 -0700 Subject: [PATCH 01/46] Added Toolchain find CRTP --- .../include/toolchain/api/toolchain_find.h | 46 ++++++++ .../toolchain/include/toolchain/toolchain.h | 2 + .../lib/toolchain/src/api/toolchain_find.cpp | 105 ++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h create mode 100644 buildcc/lib/toolchain/src/api/toolchain_find.cpp diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h new file mode 100644 index 00000000..d9dafe3e --- /dev/null +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h @@ -0,0 +1,46 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAIN_TOOLCHAIN_FIND_H_ +#define TOOLCHAIN_TOOLCHAIN_FIND_H_ + +#include +#include +#include +#include + +#include "schema/path.h" + +namespace fs = std::filesystem; + +namespace buildcc { + +struct ToolchainFindConfig { + ToolchainFindConfig() = default; + + fs_unordered_set absolute_search_paths; + std::unordered_set env_vars{"PATH"}; +}; + +template class ToolchainFind { +public: + fs_unordered_set + Find(const ToolchainFindConfig &config = ToolchainFindConfig()); +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index f46cc2ad..30a39741 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -25,6 +25,7 @@ #include "toolchain/common/toolchain_config.h" #include "toolchain/api/flag_api.h" +#include "toolchain/api/toolchain_find.h" #include "toolchain/api/toolchain_verify.h" namespace buildcc { @@ -54,6 +55,7 @@ struct ToolchainBinaries { // Base toolchain class class Toolchain : public internal::FlagApi, + public ToolchainFind, public ToolchainVerify { public: public: diff --git a/buildcc/lib/toolchain/src/api/toolchain_find.cpp b/buildcc/lib/toolchain/src/api/toolchain_find.cpp new file mode 100644 index 00000000..570f7a4a --- /dev/null +++ b/buildcc/lib/toolchain/src/api/toolchain_find.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "toolchain/api/toolchain_find.h" + +#include "env/assert_fatal.h" +#include "env/host_os.h" +#include "env/host_os_util.h" +#include "env/util.h" + +#include "toolchain/toolchain.h" + +namespace { + +std::vector ParseEnvVarToPaths(const std::string &env_var) { + const char *path_env = getenv(env_var.c_str()); + buildcc::env::assert_fatal( + path_env != nullptr, + fmt::format("Environment variable '{}' not present", env_var)); + + constexpr const char *os_env_delim = buildcc::env::get_os_envvar_delim(); + buildcc::env::assert_fatal("OS not supported"); + std::vector paths = + buildcc::env::split(path_env, os_env_delim[0]); + + return paths; +} + +bool ContainsToolchainBinaries(const fs::directory_iterator &directory_iterator, + const buildcc::ToolchainBinaries &binaries) { + std::unordered_set bins{binaries.assembler, binaries.c_compiler, + binaries.cpp_compiler, binaries.archiver, + binaries.linker}; + std::error_code ec; + for (const auto &dir_iter : directory_iterator) { + bool is_regular_file = dir_iter.is_regular_file(ec); + if (!is_regular_file || ec) { + continue; + } + const auto &filename_without_ext = dir_iter.path().stem().string(); + // NOTE, Must match the entire filename + bins.erase(filename_without_ext); + } + return bins.empty(); +} + +} // namespace + +namespace buildcc { + +template +fs_unordered_set ToolchainFind::Find(const ToolchainFindConfig &config) { + // Initialization + T &t = static_cast(*this); + fs_unordered_set found_toolchains; + fs_unordered_set absolute_search_paths(config.absolute_search_paths); + + // Parse config envs and add it to absolute search paths + for (const std::string &env_var : config.env_vars) { + std::vector paths = ParseEnvVarToPaths(env_var); + absolute_search_paths.insert(paths.begin(), paths.end()); + } + + // Over the absolute search paths + // - Check if directory exists + // - Iterate over directory + // - Find ALL Toolchain binaries in ONE directory + // - If matched, store that path + for (const auto &search_path : absolute_search_paths) { + if (!fs::exists(search_path)) { + continue; + } + + std::error_code ec; + auto directory_iterator = fs::directory_iterator(search_path, ec); + if (ec) { + continue; + } + + bool toolchains_matched = + ContainsToolchainBinaries(directory_iterator, t.GetToolchainBinaries()); + if (toolchains_matched) { + found_toolchains.insert(search_path); + } + } + + return found_toolchains; +} + +template class ToolchainFind; + +} // namespace buildcc From 413c8f81a7046ca27930a63b42b423f3f4042d6e Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Fri, 18 Mar 2022 00:53:14 -0700 Subject: [PATCH 02/46] Added test_toolchain_find --- buildcc/lib/toolchain/CMakeLists.txt | 33 ++++++---- .../toolchain/test/test_toolchain_find.cpp | 65 +++++++++++++++++++ 2 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 buildcc/lib/toolchain/test/test_toolchain_find.cpp diff --git a/buildcc/lib/toolchain/CMakeLists.txt b/buildcc/lib/toolchain/CMakeLists.txt index 91570b7d..60ed092d 100644 --- a/buildcc/lib/toolchain/CMakeLists.txt +++ b/buildcc/lib/toolchain/CMakeLists.txt @@ -6,14 +6,14 @@ set(TOOLCHAIN_SRCS include/toolchain/common/function_lock.h # API + src/api/toolchain_find.cpp + src/api/toolchain_verify.cpp + include/toolchain/api/toolchain_find.h + include/toolchain/api/toolchain_verify.h include/toolchain/api/flag_api.h src/toolchain/toolchain.cpp include/toolchain/toolchain.h - - # Features - src/api/toolchain_verify.cpp - include/toolchain/api/toolchain_verify.h ) if (${TESTING}) add_library(mock_toolchain @@ -32,24 +32,35 @@ if (${TESTING}) ${TEST_LINK_LIBS} ) - add_executable(test_toolchain_verify - test/test_toolchain_verify.cpp + add_executable(test_toolchain_config + test/test_toolchain_config.cpp ) - target_link_libraries(test_toolchain_verify PRIVATE + target_link_libraries(test_toolchain_config PRIVATE mock_toolchain ) - add_executable(test_toolchain_config - test/test_toolchain_config.cpp + add_executable(test_toolchain_find + test/test_toolchain_find.cpp ) - target_link_libraries(test_toolchain_config PRIVATE + target_link_libraries(test_toolchain_find PRIVATE mock_toolchain ) + add_executable(test_toolchain_verify + test/test_toolchain_verify.cpp + ) + target_link_libraries(test_toolchain_verify PRIVATE + mock_toolchain + ) + + + add_test(NAME test_toolchain_config COMMAND test_toolchain_config) + add_test(NAME test_toolchain_find COMMAND test_toolchain_find + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test + ) add_test(NAME test_toolchain_verify COMMAND test_toolchain_verify WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test ) - add_test(NAME test_toolchain_config COMMAND test_toolchain_config) endif() if(${BUILDCC_BUILD_AS_SINGLE_LIB}) diff --git a/buildcc/lib/toolchain/test/test_toolchain_find.cpp b/buildcc/lib/toolchain/test/test_toolchain_find.cpp new file mode 100644 index 00000000..031d0d9c --- /dev/null +++ b/buildcc/lib/toolchain/test/test_toolchain_find.cpp @@ -0,0 +1,65 @@ +#include + +#include "toolchain/toolchain.h" + +#include "env/host_os.h" + +#include "expect_command.h" + +#include "mock_command_copier.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(ToolchainFindTestGroup) +{ + void teardown() { + mock().checkExpectations(); + mock().clear(); + } +}; +// clang-format on + +// NOTE, We are mocking the environment instead of actually querying it +TEST(ToolchainFindTestGroup, VerifyToolchain_Gcc) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", + fs::current_path().string()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainFindConfig config; + config.env_vars.clear(); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + buildcc::fs_unordered_set found_toolchains = gcc.Find(config); + CHECK_TRUE(!found_toolchains.empty()); +} + +int main(int ac, char **av) { + // buildcc::env::m::VectorStringCopier copier; + // mock().installCopier(TEST_VECTOR_STRING_TYPE, copier); + + // NOTE, Check the GCC, MSVC and Clang compilers + // Create directory and populate it with gcc and cl executables + // Linux + // toolchains/gcc + // toolchains/clang + + // Windows + // toolchains/msvc + // toolchains/mingw + // TODO, Check executables used in clang + + return CommandLineTestRunner::RunAllTests(ac, av); +} From c4897a2c814fc441944cdefe1d9cacda41243f54 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 19 Mar 2022 14:38:47 -0700 Subject: [PATCH 03/46] Update toolchain_find.cpp --- buildcc/lib/toolchain/src/api/toolchain_find.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/buildcc/lib/toolchain/src/api/toolchain_find.cpp b/buildcc/lib/toolchain/src/api/toolchain_find.cpp index 570f7a4a..cdbac76b 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_find.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_find.cpp @@ -41,9 +41,9 @@ std::vector ParseEnvVarToPaths(const std::string &env_var) { bool ContainsToolchainBinaries(const fs::directory_iterator &directory_iterator, const buildcc::ToolchainBinaries &binaries) { - std::unordered_set bins{binaries.assembler, binaries.c_compiler, - binaries.cpp_compiler, binaries.archiver, - binaries.linker}; + std::unordered_set bins({binaries.assembler, binaries.c_compiler, + binaries.cpp_compiler, + binaries.archiver, binaries.linker}); std::error_code ec; for (const auto &dir_iter : directory_iterator) { bool is_regular_file = dir_iter.is_regular_file(ec); From b6ee925dcfb5e7556c0c76f17b54c2a89cf543f4 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 19 Mar 2022 14:38:52 -0700 Subject: [PATCH 04/46] Update test_toolchain_find.cpp --- .../toolchain/test/test_toolchain_find.cpp | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/buildcc/lib/toolchain/test/test_toolchain_find.cpp b/buildcc/lib/toolchain/test/test_toolchain_find.cpp index 031d0d9c..7d8b34c8 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_find.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_find.cpp @@ -25,8 +25,7 @@ TEST_GROUP(ToolchainFindTestGroup) }; // clang-format on -// NOTE, We are mocking the environment instead of actually querying it -TEST(ToolchainFindTestGroup, VerifyToolchain_Gcc) { +TEST(ToolchainFindTestGroup, FindToolchain_ThroughEnvVar) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); @@ -46,10 +45,58 @@ TEST(ToolchainFindTestGroup, VerifyToolchain_Gcc) { CHECK_TRUE(!found_toolchains.empty()); } -int main(int ac, char **av) { - // buildcc::env::m::VectorStringCopier copier; - // mock().installCopier(TEST_VECTOR_STRING_TYPE, copier); +TEST(ToolchainFindTestGroup, FindToolchain_ThroughAbsolutePath) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + buildcc::ToolchainFindConfig config; + config.absolute_search_paths.insert(fs::current_path() / "toolchains" / + "gcc"); + config.env_vars.clear(); + + buildcc::fs_unordered_set found_toolchains = gcc.Find(config); + CHECK_TRUE(!found_toolchains.empty()); +} + +TEST(ToolchainFindTestGroup, FindToolchain_DirectoryDoesntExist) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + buildcc::ToolchainFindConfig config; + config.absolute_search_paths.insert(fs::current_path() / "toolchains" / + "directory_doesnt_exist"); + config.env_vars.clear(); + + buildcc::fs_unordered_set found_toolchains = gcc.Find(config); + CHECK_TRUE(found_toolchains.empty()); +} +TEST(ToolchainFindTestGroup, FindToolchain_NoDirectoryFound) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + buildcc::ToolchainFindConfig config; + config.absolute_search_paths.insert(fs::current_path() / "toolchains" / + "gcc" / "ar"); + config.env_vars.clear(); + + buildcc::fs_unordered_set found_toolchains = gcc.Find(config); + CHECK_TRUE(found_toolchains.empty()); +} + +TEST(ToolchainFindTestGroup, FindToolchain_NoToolchainFound) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + buildcc::ToolchainFindConfig config; + config.absolute_search_paths.insert(fs::current_path() / "toolchains"); + config.env_vars.clear(); + + buildcc::fs_unordered_set found_toolchains = gcc.Find(config); + CHECK_TRUE(found_toolchains.empty()); +} + +int main(int ac, char **av) { // NOTE, Check the GCC, MSVC and Clang compilers // Create directory and populate it with gcc and cl executables // Linux From b4a2ff6ea3b06de4ed025dd1eabe9dae7436dbda Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 19 Mar 2022 16:40:15 -0700 Subject: [PATCH 05/46] Updated toolchain_find API --- .../toolchain/include/toolchain/api/toolchain_find.h | 2 +- buildcc/lib/toolchain/src/api/toolchain_find.cpp | 7 ++++--- buildcc/lib/toolchain/test/test_toolchain_find.cpp | 10 +++++----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h index d9dafe3e..d32f9a08 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h @@ -37,7 +37,7 @@ struct ToolchainFindConfig { template class ToolchainFind { public: - fs_unordered_set + std::vector Find(const ToolchainFindConfig &config = ToolchainFindConfig()); }; diff --git a/buildcc/lib/toolchain/src/api/toolchain_find.cpp b/buildcc/lib/toolchain/src/api/toolchain_find.cpp index cdbac76b..51d508eb 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_find.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_find.cpp @@ -62,10 +62,11 @@ bool ContainsToolchainBinaries(const fs::directory_iterator &directory_iterator, namespace buildcc { template -fs_unordered_set ToolchainFind::Find(const ToolchainFindConfig &config) { +std::vector +ToolchainFind::Find(const ToolchainFindConfig &config) { // Initialization T &t = static_cast(*this); - fs_unordered_set found_toolchains; + std::vector found_toolchains; fs_unordered_set absolute_search_paths(config.absolute_search_paths); // Parse config envs and add it to absolute search paths @@ -93,7 +94,7 @@ fs_unordered_set ToolchainFind::Find(const ToolchainFindConfig &config) { bool toolchains_matched = ContainsToolchainBinaries(directory_iterator, t.GetToolchainBinaries()); if (toolchains_matched) { - found_toolchains.insert(search_path); + found_toolchains.push_back(search_path); } } diff --git a/buildcc/lib/toolchain/test/test_toolchain_find.cpp b/buildcc/lib/toolchain/test/test_toolchain_find.cpp index 7d8b34c8..ee6dcb7f 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_find.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_find.cpp @@ -41,7 +41,7 @@ TEST(ToolchainFindTestGroup, FindToolchain_ThroughEnvVar) { config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - buildcc::fs_unordered_set found_toolchains = gcc.Find(config); + std::vector found_toolchains = gcc.Find(config); CHECK_TRUE(!found_toolchains.empty()); } @@ -54,7 +54,7 @@ TEST(ToolchainFindTestGroup, FindToolchain_ThroughAbsolutePath) { "gcc"); config.env_vars.clear(); - buildcc::fs_unordered_set found_toolchains = gcc.Find(config); + std::vector found_toolchains = gcc.Find(config); CHECK_TRUE(!found_toolchains.empty()); } @@ -67,7 +67,7 @@ TEST(ToolchainFindTestGroup, FindToolchain_DirectoryDoesntExist) { "directory_doesnt_exist"); config.env_vars.clear(); - buildcc::fs_unordered_set found_toolchains = gcc.Find(config); + std::vector found_toolchains = gcc.Find(config); CHECK_TRUE(found_toolchains.empty()); } @@ -80,7 +80,7 @@ TEST(ToolchainFindTestGroup, FindToolchain_NoDirectoryFound) { "gcc" / "ar"); config.env_vars.clear(); - buildcc::fs_unordered_set found_toolchains = gcc.Find(config); + std::vector found_toolchains = gcc.Find(config); CHECK_TRUE(found_toolchains.empty()); } @@ -92,7 +92,7 @@ TEST(ToolchainFindTestGroup, FindToolchain_NoToolchainFound) { config.absolute_search_paths.insert(fs::current_path() / "toolchains"); config.env_vars.clear(); - buildcc::fs_unordered_set found_toolchains = gcc.Find(config); + std::vector found_toolchains = gcc.Find(config); CHECK_TRUE(found_toolchains.empty()); } From b127cf698a207195a63d29d01a9b801e3c94cbbf Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 19 Mar 2022 17:58:03 -0700 Subject: [PATCH 06/46] Update toolchain_find.h --- .../include/toolchain/api/toolchain_find.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h index d32f9a08..93c09e5c 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h @@ -28,11 +28,23 @@ namespace fs = std::filesystem; namespace buildcc { +/** + * @brief Configure the behaviour of Toolchain::Find API. By default searches + * the directories mentioned in the ENV{PATH} variable to find the toolchain. + * @param absolute_search_paths absolute_search_paths expect directories that + * are iterated for exact toolchain matches + * @param env_vars env_vars contain paths that are seperated by OS delimiter. + * These are converted to paths and searched similarly to absolute_search_paths + *
+ */ struct ToolchainFindConfig { - ToolchainFindConfig() = default; + ToolchainFindConfig( + const std::unordered_set &env_vars = {"PATH"}, + const fs_unordered_set &absolute_search_paths = {}) + : env_vars(env_vars), absolute_search_paths(absolute_search_paths) {} + std::unordered_set env_vars; fs_unordered_set absolute_search_paths; - std::unordered_set env_vars{"PATH"}; }; template class ToolchainFind { From 920933e3930c9e0f5661e351de7b6a619f669925 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 19 Mar 2022 17:58:45 -0700 Subject: [PATCH 07/46] Updated toolchain_verify API --- .../include/toolchain/api/toolchain_verify.h | 21 +++++++++---------- .../toolchain/include/toolchain/toolchain.h | 8 ++++++- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index a22277da..f0d376dc 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -21,9 +21,11 @@ #include #include +#include "fmt/format.h" + #include "env/logging.h" -#include "fmt/format.h" +#include "toolchain_find.h" namespace fs = std::filesystem; @@ -58,10 +60,7 @@ namespace buildcc { * @param update Updates the toolchain with absolute paths once verified
* If multiple toolchains are found, uses the first in the list */ -struct VerifyToolchainConfig { - std::vector absolute_search_paths; - std::vector env_vars{"PATH"}; - +struct ToolchainVerifyConfig : public ToolchainFindConfig { std::optional compiler_version; std::optional target_arch; @@ -76,7 +75,7 @@ struct VerifyToolchainConfig { * @param compiler_version Compiler version of the verified toolchain * @param target_arch Target architecture of the verified toolchain */ -struct VerifiedToolchain { +struct ToolchainCompilerInfo { fs::path path; std::string compiler_version; std::string target_arch; @@ -96,11 +95,11 @@ template class ToolchainVerify { * multiple toolchains of similar names with different versions. Collect all * of them */ - std::vector - Verify(const VerifyToolchainConfig &config = VerifyToolchainConfig()); + std::vector + Verify(const ToolchainVerifyConfig &config = ToolchainVerifyConfig()); protected: - VerifiedToolchain verified_toolchain_; + ToolchainCompilerInfo verified_toolchain_; }; } // namespace buildcc @@ -112,9 +111,9 @@ constexpr const char *const kVerifiedToolchainFormat = R"({{ }})"; template <> -struct fmt::formatter : formatter { +struct fmt::formatter : formatter { template - auto format(const buildcc::VerifiedToolchain &vt, FormatContext &ctx) { + auto format(const buildcc::ToolchainCompilerInfo &vt, FormatContext &ctx) { std::string verified_toolchain_info = fmt::format(kVerifiedToolchainFormat, vt.path.string(), vt.compiler_version, vt.target_arch); diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 30a39741..4cba2b9c 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -108,9 +108,15 @@ class Toolchain : public internal::FlagApi, }; private: - virtual void UpdateConfig(ToolchainConfig &config) { (void)config; } void Initialize(); + virtual void UpdateConfig(ToolchainConfig &config) { (void)config; } + virtual std::optional + VerifySelectedToolchainPath(const fs::path &selected_path) { + (void)selected_path; + return {}; + } + private: friend class internal::FlagApi; friend class ToolchainVerify; From 486b5c318785adcc1c6e19020badbbffe954a542 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 19 Mar 2022 18:09:19 -0700 Subject: [PATCH 08/46] Update test_toolchain_verify.cpp --- .../toolchain/test/test_toolchain_verify.cpp | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 0fce266c..421cf7d2 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -43,11 +43,11 @@ TEST(ToolchainTestGroup, VerifyToolchain_Gcc) { CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_TRUE(!verified_toolchains.empty()); @@ -72,11 +72,11 @@ TEST(ToolchainTestGroup, VerifyToolchain_Clang) { CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - std::vector verified_toolchains = + std::vector verified_toolchains = clang.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_TRUE(!verified_toolchains.empty()); @@ -108,11 +108,11 @@ TEST(ToolchainTestGroup, VerifyToolchain_Msvc) { CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - std::vector verified_toolchains = + std::vector verified_toolchains = msvc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_TRUE(!verified_toolchains.empty()); @@ -133,11 +133,11 @@ TEST(ToolchainTestGroup, VerifyToolchain_BadCompilerId) { CHECK_TRUE(custom_buildcc_path != nullptr); UT_PRINT(custom_buildcc_path); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.env_vars.push_back("CUSTOM_BUILDCC_PATH"); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_TRUE(!verified_toolchains.empty()); @@ -149,12 +149,12 @@ TEST(ToolchainTestGroup, VerifyToolchain_BadAbsolutePath) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( + config.absolute_search_paths.insert( (fs::current_path() / "does_not_exist").string()); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_TRUE(verified_toolchains.empty()); @@ -164,12 +164,12 @@ TEST(ToolchainTestGroup, VerifyToolchain_PathContainsDir) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( + config.absolute_search_paths.insert( (fs::current_path() / "toolchains").string()); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_TRUE(verified_toolchains.empty()); @@ -179,9 +179,9 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_CompilerVersion) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( + config.absolute_search_paths.insert( (fs::current_path() / "toolchains" / "gcc").string()); config.compiler_version = "10.2.1"; @@ -190,7 +190,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_CompilerVersion) { buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_EQUAL(verified_toolchains.size(), 1); @@ -201,9 +201,9 @@ TEST(ToolchainTestGroup, buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( + config.absolute_search_paths.insert( (fs::current_path() / "toolchains" / "gcc").string()); config.compiler_version = "11.0.0"; @@ -212,7 +212,7 @@ TEST(ToolchainTestGroup, buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_EQUAL(verified_toolchains.size(), 0); @@ -222,9 +222,9 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArch) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( + config.absolute_search_paths.insert( (fs::current_path() / "toolchains" / "gcc").string()); config.target_arch = "arm-none-eabi"; @@ -233,7 +233,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArch) { buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_EQUAL(verified_toolchains.size(), 1); @@ -243,9 +243,9 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArchFailure) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( + config.absolute_search_paths.insert( (fs::current_path() / "toolchains" / "gcc").string()); config.target_arch = "none"; @@ -254,7 +254,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArchFailure) { buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_EQUAL(verified_toolchains.size(), 0); @@ -264,9 +264,9 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_BothFailure) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( + config.absolute_search_paths.insert( (fs::current_path() / "toolchains" / "gcc").string()); config.compiler_version = "none"; config.target_arch = "none"; @@ -276,7 +276,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_BothFailure) { buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_EQUAL(verified_toolchains.size(), 0); @@ -286,9 +286,9 @@ TEST(ToolchainTestGroup, VerifyToolchain_UpdateFalse) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( + config.absolute_search_paths.insert( (fs::current_path() / "toolchains" / "gcc").string()); // config.compiler_version = "none"; // config.target_arch = "none"; @@ -299,7 +299,7 @@ TEST(ToolchainTestGroup, VerifyToolchain_UpdateFalse) { buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_EQUAL(verified_toolchains.size(), 1); @@ -318,12 +318,12 @@ TEST(ToolchainTestGroup, VerifyToolchain_LockedFolder) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - buildcc::VerifyToolchainConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.absolute_search_paths.push_back( + config.absolute_search_paths.insert( (fs::current_path() / "toolchains" / "gcc").string()); - std::vector verified_toolchains = + std::vector verified_toolchains = gcc.Verify(config); UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); CHECK_TRUE(verified_toolchains.empty()); From 36572e3cf682e2925c397362754b2b79d1c61200 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sat, 19 Mar 2022 18:23:28 -0700 Subject: [PATCH 09/46] Updated toolchain find --- buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h | 2 +- buildcc/lib/toolchain/src/api/toolchain_find.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h index 93c09e5c..53b828d0 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h @@ -50,7 +50,7 @@ struct ToolchainFindConfig { template class ToolchainFind { public: std::vector - Find(const ToolchainFindConfig &config = ToolchainFindConfig()); + Find(const ToolchainFindConfig &config = ToolchainFindConfig()) const; }; } // namespace buildcc diff --git a/buildcc/lib/toolchain/src/api/toolchain_find.cpp b/buildcc/lib/toolchain/src/api/toolchain_find.cpp index 51d508eb..9cb6a2f8 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_find.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_find.cpp @@ -63,9 +63,9 @@ namespace buildcc { template std::vector -ToolchainFind::Find(const ToolchainFindConfig &config) { +ToolchainFind::Find(const ToolchainFindConfig &config) const { // Initialization - T &t = static_cast(*this); + const T &t = static_cast(*this); std::vector found_toolchains; fs_unordered_set absolute_search_paths(config.absolute_search_paths); From bcd1bcbe5c43967e965807aeebccca8d6cdbd654 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 20 Mar 2022 01:23:24 -0700 Subject: [PATCH 10/46] Update toolchain_find.h --- buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h index 53b828d0..4929bc5e 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_find.h @@ -36,6 +36,10 @@ namespace buildcc { * @param env_vars env_vars contain paths that are seperated by OS delimiter. * These are converted to paths and searched similarly to absolute_search_paths *
+ * NOTE: env_vars must contain single absolute paths or multiple absolute + * paths seperated by OS delimiter
+ * Example: [Windows] "absolute_path_1;absolute_path_2;..."
+ * Example: [Linux] "absolute_path_1:absolute_path_2:..."
*/ struct ToolchainFindConfig { ToolchainFindConfig( From 17c6317e2a823fecfd5efa6cd5a32755f68887bd Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 20 Mar 2022 01:24:43 -0700 Subject: [PATCH 11/46] Update toolchain.h --- buildcc/lib/toolchain/include/toolchain/toolchain.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 4cba2b9c..d3649f66 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -112,8 +112,10 @@ class Toolchain : public internal::FlagApi, virtual void UpdateConfig(ToolchainConfig &config) { (void)config; } virtual std::optional - VerifySelectedToolchainPath(const fs::path &selected_path) { + VerifySelectedToolchainPath(const fs::path &selected_path, + const ToolchainFindConfig &verify_config) const { (void)selected_path; + (void)verify_config; return {}; } From d9bfeda7f147dbd008eb0f440a50ae7bb752e899 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 20 Mar 2022 01:26:36 -0700 Subject: [PATCH 12/46] Updated toolchain_verify API --- .../include/toolchain/api/toolchain_verify.h | 40 +- .../toolchain/src/api/toolchain_verify.cpp | 293 ++------------ .../toolchain/test/test_toolchain_verify.cpp | 376 ++++-------------- 3 files changed, 129 insertions(+), 580 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index f0d376dc..e4de131d 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -31,42 +31,6 @@ namespace fs = std::filesystem; namespace buildcc { -/** - * @brief Configure the behaviour of Toolchain::Verify API. By default searches - * the directories mentioned in the ENV{PATH} variable to find the toolchain. - * @param absolute_search_paths absolute_search_paths expect directories that - * are iterated for exact toolchain matches - * @param env_vars env_vars contain paths that are seperated by OS delimiter. - * These are converted to paths and searched similarly to absolute_search_paths - *
- * NOTE: env_vars must contain single absolute paths or multiple absolute - * paths seperated by OS delimiter
- * Example: [Windows] "absolute_path_1;absolute_path_2;..."
- * Example: [Linux] "absolute_path_1:absolute_path_2:..."
- * @param compiler_version Optionally supply a compiler version if multiple - * toolchains of the same family/id are installed
- * Example: [GCC/MinGW/Clang] {compiler} -dumpversion
- * Example: [MSVC] getenv(VSCMD_VER)
- * For [MSVC] make sure to use `vcvarsall.bat {flavour}` to activate your - * toolchain - * @param target_arch Optionally supply a target architecture if multiple - * toolchains of the same family/id are installed but target different platforms - *
- * Example: [GCC/MinGW/Clang] {compiler} -dumpmachine
- * Example: [MSVC] getenv(VSCMD_ARG_HOST_ARCH) + - * getenv(VSCMD_ARG_TGT_ARCH)
- * For [MSVC] make sure to use `vcvarsall.bat {flavour}` to activate your - * toolchain - * @param update Updates the toolchain with absolute paths once verified
- * If multiple toolchains are found, uses the first in the list - */ -struct ToolchainVerifyConfig : public ToolchainFindConfig { - std::optional compiler_version; - std::optional target_arch; - - bool update{true}; -}; - /** * @brief Verified Toolchain information * @param path Absolute host path where ALL the toolchain executables are found @@ -95,8 +59,8 @@ template class ToolchainVerify { * multiple toolchains of similar names with different versions. Collect all * of them */ - std::vector - Verify(const ToolchainVerifyConfig &config = ToolchainVerifyConfig()); + ToolchainCompilerInfo + Verify(const ToolchainFindConfig &config = ToolchainFindConfig()); protected: ToolchainCompilerInfo verified_toolchain_; diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 157a7c1e..16f0b32a 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -31,261 +31,52 @@ #include "env/command.h" -namespace { -// Constants - -// Functions -std::vector ParseEnvVarToPaths(const std::string &env_var) { - const char *path_env = getenv(env_var.c_str()); - buildcc::env::assert_fatal( - path_env != nullptr, - fmt::format("Environment variable '{}' not present", env_var)); - - constexpr const char *os_env_delim = buildcc::env::get_os_envvar_delim(); - buildcc::env::assert_fatal("OS not supported"); - std::vector paths = - buildcc::env::split(path_env, os_env_delim[0]); - - return paths; -} - -std::string GetGccCompilerVersion(const buildcc::env::Command &command) { - std::vector stdout_data; - bool executed = buildcc::env::Command::Execute( - command.Construct("{compiler} -dumpversion"), {}, &stdout_data); - buildcc::env::assert_fatal( - executed, "GetCompilerVersion command not executed successfully"); - return stdout_data.at(0); -} - -std::string GetMsvcCompilerVersion() { - // Done VSCMD_VER - const char *vscmd_version = getenv("VSCMD_VER"); - buildcc::env::assert_fatal( - vscmd_version != nullptr, - "Setup Visual Studio build tools. Call `vcvarsall.bat {platform}` to " - "setup your target and host"); - return vscmd_version; -} - -std::optional -GetCompilerVersion(const fs::path &absolute_path, - const buildcc::Toolchain &toolchain) { - buildcc::env::Command command; - command.AddDefaultArgument( - "compiler", - (absolute_path / toolchain.GetCppCompiler()).make_preferred().string()); - - std::optional compiler_version; - switch (toolchain.GetId()) { - case buildcc::ToolchainId::Gcc: - case buildcc::ToolchainId::MinGW: - case buildcc::ToolchainId::Clang: - compiler_version = GetGccCompilerVersion(command); - break; - case buildcc::ToolchainId::Msvc: - compiler_version = GetMsvcCompilerVersion(); - break; - default: - buildcc::env::log_warning(__FUNCTION__, - "Operation not supported on this compiler"); - compiler_version = {}; - break; - } - return compiler_version; -} - -std::string GetGccTargetArchitecture(const buildcc::env::Command &command) { - std::vector stdout_data; - bool executed = buildcc::env::Command::Execute( - command.Construct("{compiler} -dumpmachine"), {}, &stdout_data); - buildcc::env::assert_fatal( - executed, "GetCompilerArchitecture command not executed successfully"); - return stdout_data.at(0); -} - -std::string GetMsvcTargetArchitecture() { - // DONE, Read `VSCMD_ARG_HOST_ARCH` from env path - // DONE, Read `VSCMD_ARG_TGT_ARCH` from env path - const char *vs_host_arch = getenv("VSCMD_ARG_HOST_ARCH"); - const char *vs_target_arch = getenv("VSCMD_ARG_TGT_ARCH"); - buildcc::env::assert_fatal( - (vs_host_arch != nullptr) && (vs_target_arch != nullptr), - "Setup Visual Studio build tools. Call `vcvarsall.bat {platform}` to " - "setup your target and host"); - - // DONE, Concat them! - return fmt::format("{}_{}", vs_host_arch, vs_target_arch); -} - -std::optional -GetCompilerArchitecture(const fs::path &absolute_path, - const buildcc::Toolchain &toolchain) { - buildcc::env::Command command; - command.AddDefaultArgument( - "compiler", - (absolute_path / toolchain.GetCppCompiler()).make_preferred().string()); - std::optional target_arch; - switch (toolchain.GetId()) { - case buildcc::ToolchainId::Gcc: - case buildcc::ToolchainId::MinGW: - case buildcc::ToolchainId::Clang: - target_arch = GetGccTargetArchitecture(command); - break; - case buildcc::ToolchainId::Msvc: - target_arch = GetMsvcTargetArchitecture(); - break; - default: - buildcc::env::log_warning(__FUNCTION__, - "Operation not supported on this compiler"); - target_arch = {}; - break; - } - return target_arch; -} - -class ToolchainMatcher { -public: - explicit ToolchainMatcher(const buildcc::Toolchain &toolchain) - : toolchain_(toolchain) {} - - void FillWithToolchainFilenames() { - constexpr const char *os_executable_ext = - buildcc::env::get_os_executable_extension(); - buildcc::env::assert_fatal( - "OS not supported"); - - matcher_.clear(); - matcher_.insert( - fmt::format("{}{}", toolchain_.GetAssembler(), os_executable_ext)); - matcher_.insert( - fmt::format("{}{}", toolchain_.GetCCompiler(), os_executable_ext)); - matcher_.insert( - fmt::format("{}{}", toolchain_.GetCppCompiler(), os_executable_ext)); - matcher_.insert( - fmt::format("{}{}", toolchain_.GetArchiver(), os_executable_ext)); - matcher_.insert( - fmt::format("{}{}", toolchain_.GetLinker(), os_executable_ext)); - } - - void Check(const std::string &filename) { matcher_.erase(filename); } - bool Found() { return matcher_.empty(); } - -private: - const buildcc::Toolchain &toolchain_; - - std::unordered_set matcher_; -}; - -} // namespace - namespace buildcc { template -std::vector -ToolchainVerify::Verify(const VerifyToolchainConfig &config) { - // TODO, Convert this to fs::path eventually - std::unordered_set absolute_search_paths{ - config.absolute_search_paths.begin(), config.absolute_search_paths.end()}; - - // Parse config envs - for (const std::string &env_var : config.env_vars) { - std::vector paths = ParseEnvVarToPaths(env_var); - for (const auto &p : paths) { - absolute_search_paths.insert(p); - } - } - - std::vector verified_toolchains; +ToolchainCompilerInfo +ToolchainVerify::Verify(const ToolchainFindConfig &config) { T &t = static_cast(*this); - - ToolchainMatcher matcher(t); - matcher.FillWithToolchainFilenames(); - // Iterate over absolute search paths - // [Verification] Match ALL toolchains PER directory - for (const std::string &pstr : absolute_search_paths) { - fs::path p{pstr}; - if (!fs::exists(p)) { - continue; - } - - std::error_code ec; - auto directory_iterator = fs::directory_iterator(p, ec); - if (ec) { - continue; - } - - // For each directory, Check if ALL toolchain filenames are found - for (const auto &dir_iter : directory_iterator) { - bool is_regular_file = dir_iter.is_regular_file(ec); - if (!is_regular_file || ec) { - continue; - } - const auto &filename = dir_iter.path().filename().string(); - matcher.Check(filename); - } - - // Store verified toolchain path if found - if (matcher.Found()) { - env::log_info(__FUNCTION__, fmt::format("Found: {}", p.string())); - - VerifiedToolchain vt; - vt.path = p; - vt.compiler_version = env::trim(GetCompilerVersion(p, t).value_or("")); - vt.target_arch = env::trim(GetCompilerArchitecture(p, t).value_or("")); - - // Check add - bool add{true}; - if (config.compiler_version.has_value()) { - add = add && (config.compiler_version.value() == vt.compiler_version); - } - if (config.target_arch.has_value()) { - add = add && (config.target_arch.value() == vt.target_arch); - } - if (add) { - verified_toolchains.push_back(vt); - } - } - - // Reset - matcher.FillWithToolchainFilenames(); - } - - if (config.update && !verified_toolchains.empty()) { - constexpr const char *os_executable_ext = - buildcc::env::get_os_executable_extension(); - buildcc::env::assert_fatal( - "OS not supported"); - - verified_toolchain_ = verified_toolchains[0]; - t.binaries_.assembler = - (verified_toolchain_.path / - fmt::format("{}{}", t.binaries_.assembler, os_executable_ext)) - .make_preferred() - .string(); - t.binaries_.c_compiler = - (verified_toolchain_.path / - fmt::format("{}{}", t.binaries_.c_compiler, os_executable_ext)) - .make_preferred() - .string(); - t.binaries_.cpp_compiler = - (verified_toolchain_.path / - fmt::format("{}{}", t.binaries_.cpp_compiler, os_executable_ext)) - .make_preferred() - .string(); - t.binaries_.archiver = - (verified_toolchain_.path / - fmt::format("{}{}", t.binaries_.archiver, os_executable_ext)) - .make_preferred() - .string(); - t.binaries_.linker = - (verified_toolchain_.path / - fmt::format("{}{}", t.binaries_.linker, os_executable_ext)) - .make_preferred() - .string(); - } - - return verified_toolchains; + std::vector toolchain_paths = t.Find(config); + env::assert_fatal(!toolchain_paths.empty(), "No toolchains found"); + std::optional op_toolchain_compiler_info = + t.VerifySelectedToolchainPath(toolchain_paths[0], config); + env::assert_fatal(op_toolchain_compiler_info.has_value(), + "Could not verify toolchain"); + + ToolchainCompilerInfo toolchain_compiler_info = + op_toolchain_compiler_info.value(); + constexpr const char *const executable_ext = + env::get_os_executable_extension(); + env::assert_fatal( + "Host executable extension not supported"); + + // Update the compilers + t.binaries_.assembler = + (toolchain_compiler_info.path / + fmt::format("{}{}", t.binaries_.assembler, executable_ext)) + .make_preferred() + .string(); + t.binaries_.c_compiler = + (toolchain_compiler_info.path / + fmt::format("{}{}", t.binaries_.c_compiler, executable_ext)) + .make_preferred() + .string(); + t.binaries_.cpp_compiler = + (toolchain_compiler_info.path / + fmt::format("{}{}", t.binaries_.cpp_compiler, executable_ext)) + .make_preferred() + .string(); + t.binaries_.archiver = + (toolchain_compiler_info.path / + fmt::format("{}{}", t.binaries_.archiver, executable_ext)) + .make_preferred() + .string(); + t.binaries_.linker = (toolchain_compiler_info.path / + fmt::format("{}{}", t.binaries_.linker, executable_ext)) + .make_preferred() + .string(); + return toolchain_compiler_info; } template class ToolchainVerify; diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 421cf7d2..e9a42456 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -3,6 +3,7 @@ #include "toolchain/toolchain.h" #include "env/host_os.h" +#include "env/host_os_util.h" #include "expect_command.h" @@ -16,7 +17,7 @@ #include "CppUTestExt/MockSupport.h" // clang-format off -TEST_GROUP(ToolchainTestGroup) +TEST_GROUP(ToolchainVerifyTestGroup) { void teardown() { mock().checkExpectations(); @@ -25,318 +26,111 @@ TEST_GROUP(ToolchainTestGroup) }; // clang-format on -// NOTE, We are mocking the environment instead of actually querying it -TEST(ToolchainTestGroup, VerifyToolchain_Gcc) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - std::vector version_stdout_data{"version"}; - std::vector arch_stdout_data{"arch"}; - buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); - buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); - - std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", - fs::current_path().string()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(!verified_toolchains.empty()); - STRCMP_EQUAL(verified_toolchains[0].compiler_version.c_str(), "version"); - STRCMP_EQUAL(verified_toolchains[0].target_arch.c_str(), "arch"); -} - -TEST(ToolchainTestGroup, 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().string()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - std::vector verified_toolchains = - clang.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(!verified_toolchains.empty()); - STRCMP_EQUAL(verified_toolchains[0].compiler_version.c_str(), "version"); - STRCMP_EQUAL(verified_toolchains[0].target_arch.c_str(), "arch"); -} - -TEST(ToolchainTestGroup, VerifyToolchain_Msvc) { - buildcc::Toolchain msvc(buildcc::ToolchainId::Msvc, "msvc", "cl", "cl", "cl", - "lib", "link"); - // Setup ENV - // VSCMD_VER - std::string vscmd_ver = std::string("VSCMD_VER=version"); - // VSCMD_ARG_HOST_ARCH - std::string host_arch = std::string("VSCMD_ARG_HOST_ARCH=host_arch"); - // VSCMD_ARG_TGT_ARCH - std::string tgt_arch = std::string("VSCMD_ARG_TGT_ARCH=tgt_arch"); +class TestToolchain : public buildcc::Toolchain { +public: + TestToolchain() + : Toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", + "ld") {} + +private: + virtual std::optional + VerifySelectedToolchainPath( + const fs::path &selected_path, + const buildcc::ToolchainFindConfig &verify_config) const override { + (void)selected_path; + (void)verify_config; + mock().actualCall("VerifySelectedToolchainPath").onObject(this); + if (!mock().getData("success").getBoolValue()) { + return {}; + } + + buildcc::ToolchainCompilerInfo compiler_info; + compiler_info.path = mock().getData("path").getStringValue(); + compiler_info.target_arch = mock().getData("target_arch").getStringValue(); + compiler_info.compiler_version = + mock().getData("compiler_version").getStringValue(); + return compiler_info; + } +}; - CHECK_TRUE(putenv(vscmd_ver.data()) == 0); - CHECK_TRUE(putenv(host_arch.data()) == 0); - CHECK_TRUE(putenv(tgt_arch.data()) == 0); +// NOTE, We are mocking the environment instead of actually querying it +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Success) { + TestToolchain gcc; + { + std::string putenv_str = fmt::format( + "CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path().string()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + } - // MSVC Compiler - std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/msvc", - fs::current_path().string()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); + mock().expectOneCall("VerifySelectedToolchainPath").onObject(&gcc); + mock().setData("success", true); + mock().setData("path", "dummy/path"); + mock().setData("compiler_version", "version"); + mock().setData("target_arch", "arch"); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + buildcc::ToolchainCompilerInfo verified_toolchains = gcc.Verify(config); - std::vector verified_toolchains = - msvc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(!verified_toolchains.empty()); - STRCMP_EQUAL(verified_toolchains[0].compiler_version.c_str(), "version"); - STRCMP_EQUAL(verified_toolchains[0].target_arch.c_str(), - "host_arch_tgt_arch"); + // CHECK_TRUE(!verified_toolchains.empty()); + STRCMP_EQUAL(verified_toolchains.compiler_version.c_str(), "version"); + STRCMP_EQUAL(verified_toolchains.target_arch.c_str(), "arch"); } -TEST(ToolchainTestGroup, VerifyToolchain_BadCompilerId) { - buildcc::Toolchain gcc((buildcc::ToolchainId)65535, "gcc", "as", "gcc", "g++", - "ar", "ld"); +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Failure) { + TestToolchain gcc; + { + std::string putenv_str = fmt::format( + "CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path().string()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + } - std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", - fs::current_path().string()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); + mock().expectOneCall("VerifySelectedToolchainPath").onObject(&gcc); + mock().setData("success", false); + // mock().setData("path", "dummy/path"); + // mock().setData("compiler_version", "version"); + // mock().setData("target_arch", "arch"); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(!verified_toolchains.empty()); - STRCMP_EQUAL(verified_toolchains[0].compiler_version.c_str(), ""); - STRCMP_EQUAL(verified_toolchains[0].target_arch.c_str(), ""); -} - -TEST(ToolchainTestGroup, VerifyToolchain_BadAbsolutePath) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "does_not_exist").string()); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(verified_toolchains.empty()); -} - -TEST(ToolchainTestGroup, VerifyToolchain_PathContainsDir) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "toolchains").string()); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(verified_toolchains.empty()); -} - -TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_CompilerVersion) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "toolchains" / "gcc").string()); - config.compiler_version = "10.2.1"; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"none"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 1); -} - -TEST(ToolchainTestGroup, - VerifyToolchain_ConditionalAdd_CompilerVersionFailure) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "toolchains" / "gcc").string()); - config.compiler_version = "11.0.0"; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"none"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 0); -} - -TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArch) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "toolchains" / "gcc").string()); - config.target_arch = "arm-none-eabi"; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"arm-none-eabi"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 1); + CHECK_THROWS(std::exception, gcc.Verify(config)); } -TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_TargetArchFailure) { +TEST(ToolchainVerifyTestGroup, VerifyToolchain_FailureBaseToolchain) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "toolchains" / "gcc").string()); - config.target_arch = "none"; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"arm-none-eabi"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 0); -} - -TEST(ToolchainTestGroup, VerifyToolchain_ConditionalAdd_BothFailure) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "toolchains" / "gcc").string()); - config.compiler_version = "none"; - config.target_arch = "none"; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"arm-none-eabi"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 0); -} - -TEST(ToolchainTestGroup, VerifyToolchain_UpdateFalse) { - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); - - buildcc::ToolchainVerifyConfig config; - config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "toolchains" / "gcc").string()); - // config.compiler_version = "none"; - // config.target_arch = "none"; - config.update = false; - - std::vector compiler_version{"10.2.1"}; - std::vector arch{"arm-none-eabi"}; - buildcc::env::m::CommandExpect_Execute(1, true, &compiler_version, nullptr); - buildcc::env::m::CommandExpect_Execute(1, true, &arch, nullptr); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_EQUAL(verified_toolchains.size(), 1); -} - -#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__MINGW64__) - -TEST(ToolchainTestGroup, VerifyToolchain_LockedFolder) { - std::error_code err; - fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::none, - err); - if (err) { - FAIL_TEST("Could not set file permissions"); + { + std::string putenv_str = fmt::format( + "CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path().string()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); } - buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", - "ar", "ld"); + // mock().expectOneCall("VerifySelectedToolchainPath").onObject(&gcc); + // mock().setData("success", false); + // mock().setData("path", "dummy/path"); + // mock().setData("compiler_version", "version"); + // mock().setData("target_arch", "arch"); - buildcc::ToolchainVerifyConfig config; + buildcc::ToolchainFindConfig config; config.env_vars.clear(); - config.absolute_search_paths.insert( - (fs::current_path() / "toolchains" / "gcc").string()); - - std::vector verified_toolchains = - gcc.Verify(config); - UT_PRINT(std::to_string(verified_toolchains.size()).c_str()); - CHECK_TRUE(verified_toolchains.empty()); - - fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::all, - err); - if (err) { - FAIL_TEST("Could not set file permissions"); - } + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + CHECK_THROWS(std::exception, gcc.Verify(config)); } -#endif - int main(int ac, char **av) { buildcc::env::m::VectorStringCopier copier; mock().installCopier(TEST_VECTOR_STRING_TYPE, copier); From 7a5b3dc0451282c27aaabcafd0ae62db61d84fae Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 20 Mar 2022 01:27:04 -0700 Subject: [PATCH 13/46] Update toolchain_setup.cpp --- buildexe/src/toolchain_setup.cpp | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/buildexe/src/toolchain_setup.cpp b/buildexe/src/toolchain_setup.cpp index 198bf40d..ddb331f0 100644 --- a/buildexe/src/toolchain_setup.cpp +++ b/buildexe/src/toolchain_setup.cpp @@ -25,28 +25,7 @@ constexpr const char *const kTag = "BuildExe"; namespace buildcc { void find_toolchain_verify(BaseToolchain &toolchain) { - auto verified_toolchains = toolchain.Verify(); - env::assert_fatal(!verified_toolchains.empty(), - "Toolchain could not be verified. Please input correct " - "Gcc, Msvc, Clang or MinGW toolchain executable names"); - if (verified_toolchains.size() > 1) { - env::log_info( - kTag, - fmt::format( - "Found {} toolchains. By default using the first added" - "toolchain. Modify your environment `PATH` information if you " - "would like compiler precedence when similar compilers are " - "detected in different folders", - verified_toolchains.size())); - } - - // Print - int counter = 1; - for (const auto &vt : verified_toolchains) { - std::string info = fmt::format("{}. : {}", counter, vt.ToString()); - env::log_info("Host Toolchain", info); - counter++; - } + (void)toolchain.Verify(); } void host_toolchain_verify(const BaseToolchain &toolchain) { From 5c69b312977ea470dab2ed50a8b2a96d6ed67951 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 20 Mar 2022 02:17:15 -0700 Subject: [PATCH 14/46] Update build.cpp --- example/hybrid/single/build.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example/hybrid/single/build.cpp b/example/hybrid/single/build.cpp index 3abace55..b8b104d5 100644 --- a/example/hybrid/single/build.cpp +++ b/example/hybrid/single/build.cpp @@ -24,8 +24,7 @@ int main(int argc, char **argv) { // 4. Build steps // Explicit toolchain - target pairs Toolchain_gcc gcc; - auto verified_toolchains = gcc.Verify(); - env::assert_fatal(!verified_toolchains.empty(), "GCC Toolchain not found"); + gcc.Verify(); ExecutableTarget_gcc hello_world("hello_world", gcc, ""); From 0c71f62c468eac7107da5b37476d08b6128c9829 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 20 Mar 2022 02:57:41 -0700 Subject: [PATCH 15/46] Update test_toolchain_verify.cpp --- .../toolchain/test/test_toolchain_verify.cpp | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index e9a42456..1cb53216 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -56,15 +56,13 @@ class TestToolchain : public buildcc::Toolchain { // NOTE, We are mocking the environment instead of actually querying it TEST(ToolchainVerifyTestGroup, VerifyToolchain_Success) { TestToolchain gcc; - { - std::string putenv_str = fmt::format( - "CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path().string()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - } + std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", + fs::current_path().string()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + // UT_PRINT(custom_buildcc_path); mock().expectOneCall("VerifySelectedToolchainPath").onObject(&gcc); mock().setData("success", true); @@ -75,30 +73,28 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Success) { buildcc::ToolchainFindConfig config; config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - buildcc::ToolchainCompilerInfo verified_toolchains = gcc.Verify(config); + buildcc::ToolchainCompilerInfo verified_toolchain = gcc.Verify(config); - // CHECK_TRUE(!verified_toolchains.empty()); - STRCMP_EQUAL(verified_toolchains.compiler_version.c_str(), "version"); - STRCMP_EQUAL(verified_toolchains.target_arch.c_str(), "arch"); + // CHECK_TRUE(!verified_toolchain.empty()); + STRCMP_EQUAL(verified_toolchain.compiler_version.c_str(), "version"); + STRCMP_EQUAL(verified_toolchain.target_arch.c_str(), "arch"); } TEST(ToolchainVerifyTestGroup, VerifyToolchain_Failure) { TestToolchain gcc; - { - std::string putenv_str = fmt::format( - "CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path().string()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); - } + std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", + fs::current_path().string()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); mock().expectOneCall("VerifySelectedToolchainPath").onObject(&gcc); mock().setData("success", false); - // mock().setData("path", "dummy/path"); - // mock().setData("compiler_version", "version"); - // mock().setData("target_arch", "arch"); + mock().setData("path", "dummy/path"); + mock().setData("compiler_version", "version"); + mock().setData("target_arch", "arch"); buildcc::ToolchainFindConfig config; config.env_vars.clear(); From cadd0d166b81b6dd17775cded6107bcd61863ea3 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Sun, 20 Mar 2022 22:57:55 -0700 Subject: [PATCH 16/46] Updated function prototype for VerifySelectedToolchainPath --- .../toolchain/include/toolchain/toolchain.h | 4 +-- .../toolchain/src/api/toolchain_verify.cpp | 32 +++++++++++++++---- .../toolchain/test/test_toolchain_verify.cpp | 4 +-- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index d3649f66..765f0100 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -112,9 +112,9 @@ class Toolchain : public internal::FlagApi, virtual void UpdateConfig(ToolchainConfig &config) { (void)config; } virtual std::optional - VerifySelectedToolchainPath(const fs::path &selected_path, + VerifySelectedToolchainPath(const ToolchainBinaries &binaries, const ToolchainFindConfig &verify_config) const { - (void)selected_path; + (void)binaries; (void)verify_config; return {}; } diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 16f0b32a..e17660a3 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -22,7 +22,7 @@ #include -#include "toolchain/toolchain.h" +#include "schema/path.h" #include "env/assert_fatal.h" #include "env/host_os.h" @@ -31,6 +31,8 @@ #include "env/command.h" +#include "toolchain/toolchain.h" + namespace buildcc { template @@ -39,17 +41,35 @@ 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"); + + constexpr const char *const executable_ext = + env::get_os_executable_extension(); + env::assert_fatal( + "Host executable extension not supported"); + ToolchainBinaries binaries( + fmt::format("{}", + (toolchain_paths[0] / + fmt::format("{}{}", t.binaries_.assembler, executable_ext))), + fmt::format( + "{}", (toolchain_paths[0] / + fmt::format("{}{}", t.binaries_.c_compiler, executable_ext))), + fmt::format("{}", (toolchain_paths[0] / + fmt::format("{}{}", t.binaries_.cpp_compiler, + executable_ext))), + fmt::format("{}", + (toolchain_paths[0] / + fmt::format("{}{}", t.binaries_.archiver, executable_ext))), + fmt::format("{}", + (toolchain_paths[0] / + fmt::format("{}{}", t.binaries_.linker, executable_ext)))); + std::optional op_toolchain_compiler_info = - t.VerifySelectedToolchainPath(toolchain_paths[0], config); + t.VerifySelectedToolchainPath(binaries, config); env::assert_fatal(op_toolchain_compiler_info.has_value(), "Could not verify toolchain"); ToolchainCompilerInfo toolchain_compiler_info = op_toolchain_compiler_info.value(); - constexpr const char *const executable_ext = - env::get_os_executable_extension(); - env::assert_fatal( - "Host executable extension not supported"); // Update the compilers t.binaries_.assembler = diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 1cb53216..007e5f04 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -35,9 +35,9 @@ class TestToolchain : public buildcc::Toolchain { private: virtual std::optional VerifySelectedToolchainPath( - const fs::path &selected_path, + const buildcc::ToolchainBinaries &binaries, const buildcc::ToolchainFindConfig &verify_config) const override { - (void)selected_path; + (void)binaries; (void)verify_config; mock().actualCall("VerifySelectedToolchainPath").onObject(this); if (!mock().getData("success").getBoolValue()) { From 58fc92848c7f4e8cd4d08746a5d023ba1e5b53c1 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 00:46:54 -0700 Subject: [PATCH 17/46] Updated VerifySelectedToolchainPath --- buildcc/lib/toolchain/include/toolchain/toolchain.h | 4 +--- buildcc/lib/toolchain/src/api/toolchain_verify.cpp | 3 +-- buildcc/lib/toolchain/test/test_toolchain_verify.cpp | 4 +--- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 765f0100..dc8fe14a 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -112,10 +112,8 @@ class Toolchain : public internal::FlagApi, virtual void UpdateConfig(ToolchainConfig &config) { (void)config; } virtual std::optional - VerifySelectedToolchainPath(const ToolchainBinaries &binaries, - const ToolchainFindConfig &verify_config) const { + VerifySelectedToolchainPath(const ToolchainBinaries &binaries) const { (void)binaries; - (void)verify_config; return {}; } diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index e17660a3..7fe8f435 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -63,8 +63,7 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { (toolchain_paths[0] / fmt::format("{}{}", t.binaries_.linker, executable_ext)))); - std::optional op_toolchain_compiler_info = - t.VerifySelectedToolchainPath(binaries, config); + auto op_toolchain_compiler_info = t.VerifySelectedToolchainPath(binaries); env::assert_fatal(op_toolchain_compiler_info.has_value(), "Could not verify toolchain"); diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 007e5f04..ff75e048 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -35,10 +35,8 @@ class TestToolchain : public buildcc::Toolchain { private: virtual std::optional VerifySelectedToolchainPath( - const buildcc::ToolchainBinaries &binaries, - const buildcc::ToolchainFindConfig &verify_config) const override { + const buildcc::ToolchainBinaries &binaries) const override { (void)binaries; - (void)verify_config; mock().actualCall("VerifySelectedToolchainPath").onObject(this); if (!mock().getData("success").getBoolValue()) { return {}; From b0a6c541b24dff7fe4eb21f6b900c90ac699b282 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 18:46:06 -0700 Subject: [PATCH 18/46] Update toolchain_verify.cpp --- buildcc/lib/toolchain/src/api/toolchain_verify.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 7fe8f435..6344abf7 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -69,6 +69,7 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { ToolchainCompilerInfo toolchain_compiler_info = op_toolchain_compiler_info.value(); + toolchain_compiler_info.path = toolchain_paths[0]; // Update the compilers t.binaries_.assembler = From f550747afaa91c3d504f8ef5b10122d9118920ee Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 19:38:06 -0700 Subject: [PATCH 19/46] Updated specialized toolchains --- .../include/toolchains/toolchain_gcc.h | 44 +++++++++++++++++++ .../include/toolchains/toolchain_mingw.h | 6 +++ .../include/toolchains/toolchain_msvc.h | 35 +++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index 9e54351f..0a203d2f 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -27,6 +27,45 @@ constexpr const char *const kGccPchCompileExt = ".gch"; constexpr const char *const kGccPrefixIncludeDir = "-I"; constexpr const char *const kGccPrefixLibDir = "-L"; +inline 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]; +} + +inline 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]; +} + +inline std::optional +VerifyGccSelectedToolchainPath(const ToolchainBinaries &binaries) { + env::Command command; + command.AddDefaultArgument("compiler", binaries.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 {}; + } + + ToolchainCompilerInfo compiler_info; + compiler_info.compiler_version = op_compiler_version.value(); + compiler_info.target_arch = op_target_arch.value(); + return compiler_info; +} + /** * @brief Generic GCC Toolchain
* id = ToolchainId::Gcc
@@ -51,6 +90,11 @@ class Toolchain_gcc : public Toolchain { config.prefix_include_dir = kGccPrefixIncludeDir; config.prefix_lib_dir = kGccPrefixLibDir; } + + virtual std::optional + VerifySelectedToolchainPath(const ToolchainBinaries &binaries) const { + return VerifyGccSelectedToolchainPath(binaries); + } }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index 05bef7ca..21a00f12 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -19,6 +19,8 @@ #include "toolchain/toolchain.h" +#include "toolchain_gcc.h" + namespace buildcc { constexpr const char *const kMingwObjExt = ".o"; @@ -51,6 +53,10 @@ class Toolchain_mingw : public BaseToolchain { config.prefix_include_dir = kMingwPrefixIncludeDir; config.prefix_lib_dir = kMingwPrefixLibDir; } + virtual std::optional + VerifySelectedToolchainPath(const ToolchainBinaries &binaries) const { + return VerifyGccSelectedToolchainPath(binaries); + } }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index db40a8d6..787c835b 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -52,6 +52,41 @@ class Toolchain_msvc : public Toolchain { config.prefix_include_dir = kMsvcPrefixIncludeDir; config.prefix_lib_dir = kMsvcPrefixLibDir; } + + virtual std::optional + VerifySelectedToolchainPath(const ToolchainBinaries &binaries) const { + auto op_compiler_version = GetMsvcCompilerVersion(); + auto op_target_arch = GetMsvcTargetArchitecture(); + if (!op_compiler_version.has_value() || !op_target_arch.has_value()) { + return {}; + } + + 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 { + const char *vscmd_version = getenv("VSCMD_VER"); + if (vscmd_version == nullptr) { + return {}; + } + return vscmd_version; + } + + std::optional GetMsvcTargetArchitecture() const { + // 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 buildcc From b4098bb86adba3139505e98b60941429204c2168 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 19:40:02 -0700 Subject: [PATCH 20/46] Renamed ToolchainBinaries to ToolchainExecutables --- buildcc/lib/args/include/args/args.h | 10 ++-- .../toolchain/include/toolchain/toolchain.h | 38 +++++++------ .../lib/toolchain/src/api/toolchain_find.cpp | 6 +-- .../toolchain/src/api/toolchain_verify.cpp | 53 ++++++++++--------- .../toolchain/test/test_toolchain_verify.cpp | 2 +- .../include/toolchains/toolchain_gcc.h | 4 +- .../include/toolchains/toolchain_mingw.h | 2 +- .../include/toolchains/toolchain_msvc.h | 2 +- 8 files changed, 61 insertions(+), 56 deletions(-) diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index 05311272..ac7cab83 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -48,7 +48,7 @@ struct ArgToolchainState { struct ArgToolchain { ArgToolchain(){}; ArgToolchain(ToolchainId initial_id, const std::string &initial_name, - const ToolchainBinaries &initial_binaries) + const ToolchainExecutables &initial_binaries) : id(initial_id), name(initial_name), binaries(initial_binaries) {} ArgToolchain(ToolchainId initial_id, const std::string &initial_name, const std::string &initial_assembler, @@ -57,9 +57,9 @@ struct ArgToolchain { const std::string &initial_archiver, const std::string &initial_linker) : ArgToolchain(initial_id, initial_name, - ToolchainBinaries(initial_assembler, initial_c_compiler, - initial_cpp_compiler, initial_archiver, - initial_linker)) {} + ToolchainExecutables(initial_assembler, initial_c_compiler, + initial_cpp_compiler, + initial_archiver, initial_linker)) {} /** * @brief Construct a BaseToolchain from the arguments supplied through the @@ -73,7 +73,7 @@ struct ArgToolchain { ArgToolchainState state; ToolchainId id{ToolchainId::Undefined}; std::string name{""}; - ToolchainBinaries binaries; + ToolchainExecutables binaries; }; // NOTE, Incomplete without pch_compile_command diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index dc8fe14a..6a3061c9 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -39,11 +39,11 @@ enum class ToolchainId { Undefined, ///< Default value when unknown }; -struct ToolchainBinaries { - explicit ToolchainBinaries() = default; - explicit ToolchainBinaries(std::string_view as, std::string_view c, - std::string_view cpp, std::string_view ar, - std::string_view link) +struct ToolchainExecutables { + explicit ToolchainExecutables() = default; + explicit ToolchainExecutables(std::string_view as, std::string_view c, + std::string_view cpp, std::string_view ar, + std::string_view link) : assembler(as), c_compiler(c), cpp_compiler(cpp), archiver(ar), linker(link) {} std::string assembler; @@ -60,9 +60,9 @@ class Toolchain : public internal::FlagApi, public: public: Toolchain(ToolchainId id, std::string_view name, - const ToolchainBinaries &binaries, bool lock = true, + const ToolchainExecutables &binaries, bool lock = true, const ToolchainConfig &config = ToolchainConfig()) - : id_(id), name_(name), binaries_(binaries), lock_(lock), + : id_(id), name_(name), executables_(binaries), lock_(lock), config_(config) { Initialize(); } @@ -71,8 +71,8 @@ class Toolchain : public internal::FlagApi, std::string_view archiver, std::string_view linker, bool lock = true, const ToolchainConfig &config = ToolchainConfig()) : Toolchain(id, name, - ToolchainBinaries(assembler, c_compiler, cpp_compiler, - archiver, linker), + ToolchainExecutables(assembler, c_compiler, cpp_compiler, + archiver, linker), lock, config) {} Toolchain(Toolchain &&) = default; @@ -85,12 +85,16 @@ class Toolchain : public internal::FlagApi, // Getters ToolchainId GetId() const { return id_; } const std::string &GetName() const { return name_; } - const std::string &GetAssembler() const { return binaries_.assembler; } - const std::string &GetCCompiler() const { return binaries_.c_compiler; } - const std::string &GetCppCompiler() const { return binaries_.cpp_compiler; } - const std::string &GetArchiver() const { return binaries_.archiver; } - const std::string &GetLinker() const { return binaries_.linker; } - const ToolchainBinaries &GetToolchainBinaries() const { return binaries_; } + const std::string &GetAssembler() const { return executables_.assembler; } + const std::string &GetCCompiler() const { return executables_.c_compiler; } + const std::string &GetCppCompiler() const { + return executables_.cpp_compiler; + } + const std::string &GetArchiver() const { return executables_.archiver; } + const std::string &GetLinker() const { return executables_.linker; } + const ToolchainExecutables &GetToolchainExecutables() const { + return executables_; + } const FunctionLock &GetLockInfo() const { return lock_; } const ToolchainConfig &GetConfig() const { return config_; } @@ -112,7 +116,7 @@ class Toolchain : public internal::FlagApi, virtual void UpdateConfig(ToolchainConfig &config) { (void)config; } virtual std::optional - VerifySelectedToolchainPath(const ToolchainBinaries &binaries) const { + VerifySelectedToolchainPath(const ToolchainExecutables &binaries) const { (void)binaries; return {}; } @@ -124,7 +128,7 @@ class Toolchain : public internal::FlagApi, private: ToolchainId id_; std::string name_; - ToolchainBinaries binaries_; + ToolchainExecutables executables_; FunctionLock lock_; ToolchainConfig config_; diff --git a/buildcc/lib/toolchain/src/api/toolchain_find.cpp b/buildcc/lib/toolchain/src/api/toolchain_find.cpp index 9cb6a2f8..a2939cd9 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_find.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_find.cpp @@ -40,7 +40,7 @@ std::vector ParseEnvVarToPaths(const std::string &env_var) { } bool ContainsToolchainBinaries(const fs::directory_iterator &directory_iterator, - const buildcc::ToolchainBinaries &binaries) { + const buildcc::ToolchainExecutables &binaries) { std::unordered_set bins({binaries.assembler, binaries.c_compiler, binaries.cpp_compiler, binaries.archiver, binaries.linker}); @@ -91,8 +91,8 @@ ToolchainFind::Find(const ToolchainFindConfig &config) const { continue; } - bool toolchains_matched = - ContainsToolchainBinaries(directory_iterator, t.GetToolchainBinaries()); + bool toolchains_matched = ContainsToolchainBinaries( + directory_iterator, t.GetToolchainExecutables()); if (toolchains_matched) { found_toolchains.push_back(search_path); } diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 6344abf7..d1dbed18 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -46,22 +46,22 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { env::get_os_executable_extension(); env::assert_fatal( "Host executable extension not supported"); - ToolchainBinaries binaries( - fmt::format("{}", - (toolchain_paths[0] / - fmt::format("{}{}", t.binaries_.assembler, executable_ext))), - fmt::format( - "{}", (toolchain_paths[0] / - fmt::format("{}{}", t.binaries_.c_compiler, executable_ext))), + ToolchainExecutables binaries( + fmt::format("{}", (toolchain_paths[0] / + fmt::format("{}{}", t.executables_.assembler, + executable_ext))), fmt::format("{}", (toolchain_paths[0] / - fmt::format("{}{}", t.binaries_.cpp_compiler, + fmt::format("{}{}", t.executables_.c_compiler, executable_ext))), - fmt::format("{}", - (toolchain_paths[0] / - fmt::format("{}{}", t.binaries_.archiver, executable_ext))), - fmt::format("{}", - (toolchain_paths[0] / - fmt::format("{}{}", t.binaries_.linker, executable_ext)))); + fmt::format("{}", (toolchain_paths[0] / + fmt::format("{}{}", t.executables_.cpp_compiler, + executable_ext))), + fmt::format( + "{}", (toolchain_paths[0] / + fmt::format("{}{}", t.executables_.archiver, executable_ext))), + fmt::format( + "{}", (toolchain_paths[0] / + fmt::format("{}{}", t.executables_.linker, executable_ext)))); auto op_toolchain_compiler_info = t.VerifySelectedToolchainPath(binaries); env::assert_fatal(op_toolchain_compiler_info.has_value(), @@ -72,30 +72,31 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { toolchain_compiler_info.path = toolchain_paths[0]; // Update the compilers - t.binaries_.assembler = + t.executables_.assembler = + (toolchain_compiler_info.path / + fmt::format("{}{}", t.executables_.assembler, executable_ext)) + .make_preferred() + .string(); + t.executables_.c_compiler = (toolchain_compiler_info.path / - fmt::format("{}{}", t.binaries_.assembler, executable_ext)) + fmt::format("{}{}", t.executables_.c_compiler, executable_ext)) .make_preferred() .string(); - t.binaries_.c_compiler = + t.executables_.cpp_compiler = (toolchain_compiler_info.path / - fmt::format("{}{}", t.binaries_.c_compiler, executable_ext)) + fmt::format("{}{}", t.executables_.cpp_compiler, executable_ext)) .make_preferred() .string(); - t.binaries_.cpp_compiler = + t.executables_.archiver = (toolchain_compiler_info.path / - fmt::format("{}{}", t.binaries_.cpp_compiler, executable_ext)) + fmt::format("{}{}", t.executables_.archiver, executable_ext)) .make_preferred() .string(); - t.binaries_.archiver = + t.executables_.linker = (toolchain_compiler_info.path / - fmt::format("{}{}", t.binaries_.archiver, executable_ext)) + fmt::format("{}{}", t.executables_.linker, executable_ext)) .make_preferred() .string(); - t.binaries_.linker = (toolchain_compiler_info.path / - fmt::format("{}{}", t.binaries_.linker, executable_ext)) - .make_preferred() - .string(); return toolchain_compiler_info; } diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index ff75e048..eceefdf6 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -35,7 +35,7 @@ class TestToolchain : public buildcc::Toolchain { private: virtual std::optional VerifySelectedToolchainPath( - const buildcc::ToolchainBinaries &binaries) const override { + const buildcc::ToolchainExecutables &binaries) const override { (void)binaries; mock().actualCall("VerifySelectedToolchainPath").onObject(this); if (!mock().getData("success").getBoolValue()) { diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index 0a203d2f..ce13ce43 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -50,7 +50,7 @@ GetGccTargetArchitecture(const buildcc::env::Command &command) { } inline std::optional -VerifyGccSelectedToolchainPath(const ToolchainBinaries &binaries) { +VerifyGccSelectedToolchainPath(const ToolchainExecutables &binaries) { env::Command command; command.AddDefaultArgument("compiler", binaries.cpp_compiler); @@ -92,7 +92,7 @@ class Toolchain_gcc : public Toolchain { } virtual std::optional - VerifySelectedToolchainPath(const ToolchainBinaries &binaries) const { + VerifySelectedToolchainPath(const ToolchainExecutables &binaries) const { return VerifyGccSelectedToolchainPath(binaries); } }; diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index 21a00f12..5b5faeb0 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -54,7 +54,7 @@ class Toolchain_mingw : public BaseToolchain { config.prefix_lib_dir = kMingwPrefixLibDir; } virtual std::optional - VerifySelectedToolchainPath(const ToolchainBinaries &binaries) const { + VerifySelectedToolchainPath(const ToolchainExecutables &binaries) const { return VerifyGccSelectedToolchainPath(binaries); } }; diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index 787c835b..5d6545c6 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -54,7 +54,7 @@ class Toolchain_msvc : public Toolchain { } virtual std::optional - VerifySelectedToolchainPath(const ToolchainBinaries &binaries) const { + VerifySelectedToolchainPath(const ToolchainExecutables &binaries) const { auto op_compiler_version = GetMsvcCompilerVersion(); auto op_target_arch = GetMsvcTargetArchitecture(); if (!op_compiler_version.has_value() || !op_target_arch.has_value()) { From cf4326f576d6fd67ce496fc2ee71d7bb1cdec053 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 20:56:15 -0700 Subject: [PATCH 21/46] Updated specialized toolchains --- buildcc/toolchains/include/toolchains/toolchain_gcc.h | 8 ++++---- buildcc/toolchains/include/toolchains/toolchain_mingw.h | 4 ++-- buildcc/toolchains/include/toolchains/toolchain_msvc.h | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index ce13ce43..ec21057a 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -50,9 +50,9 @@ GetGccTargetArchitecture(const buildcc::env::Command &command) { } inline std::optional -VerifyGccSelectedToolchainPath(const ToolchainExecutables &binaries) { +VerifyGccSelectedToolchainPath(const ToolchainExecutables &executables) { env::Command command; - command.AddDefaultArgument("compiler", binaries.cpp_compiler); + command.AddDefaultArgument("compiler", executables.cpp_compiler); auto op_compiler_version = GetGccCompilerVersion(command); auto op_target_arch = GetGccTargetArchitecture(command); @@ -92,8 +92,8 @@ class Toolchain_gcc : public Toolchain { } virtual std::optional - VerifySelectedToolchainPath(const ToolchainExecutables &binaries) const { - return VerifyGccSelectedToolchainPath(binaries); + VerifySelectedToolchainPath(const ToolchainExecutables &executables) const { + return VerifyGccSelectedToolchainPath(executables); } }; diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index 5b5faeb0..f803401d 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -54,8 +54,8 @@ class Toolchain_mingw : public BaseToolchain { config.prefix_lib_dir = kMingwPrefixLibDir; } virtual std::optional - VerifySelectedToolchainPath(const ToolchainExecutables &binaries) const { - return VerifyGccSelectedToolchainPath(binaries); + VerifySelectedToolchainPath(const ToolchainExecutables &executables) const { + return VerifyGccSelectedToolchainPath(executables); } }; diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index 5d6545c6..0e49565e 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -54,7 +54,8 @@ class Toolchain_msvc : public Toolchain { } virtual std::optional - VerifySelectedToolchainPath(const ToolchainExecutables &binaries) const { + VerifySelectedToolchainPath(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()) { From c5b2f9e0812772916c80469a43548e5d4f426cce Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 20:56:38 -0700 Subject: [PATCH 22/46] Updated toolchains for virtual functions --- buildcc/lib/toolchain/include/toolchain/toolchain.h | 7 ++----- buildcc/lib/toolchain/src/toolchain/toolchain.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 6a3061c9..e2dd2a51 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -114,12 +114,9 @@ class Toolchain : public internal::FlagApi, private: void Initialize(); - virtual void UpdateConfig(ToolchainConfig &config) { (void)config; } + virtual void UpdateConfig(ToolchainConfig &config); virtual std::optional - VerifySelectedToolchainPath(const ToolchainExecutables &binaries) const { - (void)binaries; - return {}; - } + VerifySelectedToolchainPath(const ToolchainExecutables &binaries) const; private: friend class internal::FlagApi; diff --git a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp index 3a3ae354..014097bf 100644 --- a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp +++ b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp @@ -22,4 +22,12 @@ void Toolchain::Initialize() { UpdateConfig(config_); } void Toolchain::Lock() { lock_.Lock(); } +// PRIVATE +void Toolchain::UpdateConfig(ToolchainConfig &config) { (void)config; } +std::optional Toolchain::VerifySelectedToolchainPath( + const ToolchainExecutables &binaries) const { + (void)binaries; + return {}; +} + } // namespace buildcc From dc6808707f83496144400e9aa8ad4161fa34d7b0 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 20:57:33 -0700 Subject: [PATCH 23/46] Update args.h --- buildcc/lib/args/include/args/args.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/buildcc/lib/args/include/args/args.h b/buildcc/lib/args/include/args/args.h index ac7cab83..c687df92 100644 --- a/buildcc/lib/args/include/args/args.h +++ b/buildcc/lib/args/include/args/args.h @@ -48,8 +48,8 @@ struct ArgToolchainState { struct ArgToolchain { ArgToolchain(){}; ArgToolchain(ToolchainId initial_id, const std::string &initial_name, - const ToolchainExecutables &initial_binaries) - : id(initial_id), name(initial_name), binaries(initial_binaries) {} + const ToolchainExecutables &initial_executables) + : id(initial_id), name(initial_name), executables(initial_executables) {} ArgToolchain(ToolchainId initial_id, const std::string &initial_name, const std::string &initial_assembler, const std::string &initial_c_compiler, @@ -67,13 +67,13 @@ struct ArgToolchain { */ // TODO, Update this for lock and ToolchainConfig BaseToolchain ConstructToolchain() const { - return BaseToolchain(id, name, binaries); + return BaseToolchain(id, name, executables); } ArgToolchainState state; ToolchainId id{ToolchainId::Undefined}; std::string name{""}; - ToolchainExecutables binaries; + ToolchainExecutables executables; }; // NOTE, Incomplete without pch_compile_command From d2dce4fcc344477bf2c8f3f6102a89bb9d6fdfb7 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 20:59:57 -0700 Subject: [PATCH 24/46] Renamed binaries to executables --- .../lib/toolchain/include/toolchain/toolchain.h | 6 +++--- buildcc/lib/toolchain/src/api/toolchain_find.cpp | 15 ++++++++------- .../lib/toolchain/src/api/toolchain_verify.cpp | 4 ++-- buildcc/lib/toolchain/src/toolchain/toolchain.cpp | 4 ++-- .../lib/toolchain/test/test_toolchain_verify.cpp | 4 ++-- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index e2dd2a51..4d5023ea 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -60,9 +60,9 @@ class Toolchain : public internal::FlagApi, public: public: Toolchain(ToolchainId id, std::string_view name, - const ToolchainExecutables &binaries, bool lock = true, + const ToolchainExecutables &executables, bool lock = true, const ToolchainConfig &config = ToolchainConfig()) - : id_(id), name_(name), executables_(binaries), lock_(lock), + : id_(id), name_(name), executables_(executables), lock_(lock), config_(config) { Initialize(); } @@ -116,7 +116,7 @@ class Toolchain : public internal::FlagApi, virtual void UpdateConfig(ToolchainConfig &config); virtual std::optional - VerifySelectedToolchainPath(const ToolchainExecutables &binaries) const; + VerifySelectedToolchainPath(const ToolchainExecutables &executables) const; private: friend class internal::FlagApi; diff --git a/buildcc/lib/toolchain/src/api/toolchain_find.cpp b/buildcc/lib/toolchain/src/api/toolchain_find.cpp index a2939cd9..2c4dd8ae 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_find.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_find.cpp @@ -39,11 +39,12 @@ std::vector ParseEnvVarToPaths(const std::string &env_var) { return paths; } -bool ContainsToolchainBinaries(const fs::directory_iterator &directory_iterator, - const buildcc::ToolchainExecutables &binaries) { - std::unordered_set bins({binaries.assembler, binaries.c_compiler, - binaries.cpp_compiler, - binaries.archiver, binaries.linker}); +bool ContainsToolchainBinaries( + const fs::directory_iterator &directory_iterator, + const buildcc::ToolchainExecutables &executables) { + std::unordered_set exes( + {executables.assembler, executables.c_compiler, executables.cpp_compiler, + executables.archiver, executables.linker}); std::error_code ec; for (const auto &dir_iter : directory_iterator) { bool is_regular_file = dir_iter.is_regular_file(ec); @@ -52,9 +53,9 @@ bool ContainsToolchainBinaries(const fs::directory_iterator &directory_iterator, } const auto &filename_without_ext = dir_iter.path().stem().string(); // NOTE, Must match the entire filename - bins.erase(filename_without_ext); + exes.erase(filename_without_ext); } - return bins.empty(); + return exes.empty(); } } // namespace diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index d1dbed18..82dc703e 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -46,7 +46,7 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { env::get_os_executable_extension(); env::assert_fatal( "Host executable extension not supported"); - ToolchainExecutables binaries( + ToolchainExecutables exes( fmt::format("{}", (toolchain_paths[0] / fmt::format("{}{}", t.executables_.assembler, executable_ext))), @@ -63,7 +63,7 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { "{}", (toolchain_paths[0] / fmt::format("{}{}", t.executables_.linker, executable_ext)))); - auto op_toolchain_compiler_info = t.VerifySelectedToolchainPath(binaries); + auto op_toolchain_compiler_info = t.VerifySelectedToolchainPath(exes); env::assert_fatal(op_toolchain_compiler_info.has_value(), "Could not verify toolchain"); diff --git a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp index 014097bf..00ec0a08 100644 --- a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp +++ b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp @@ -25,8 +25,8 @@ void Toolchain::Lock() { lock_.Lock(); } // PRIVATE void Toolchain::UpdateConfig(ToolchainConfig &config) { (void)config; } std::optional Toolchain::VerifySelectedToolchainPath( - const ToolchainExecutables &binaries) const { - (void)binaries; + const ToolchainExecutables &executables) const { + (void)executables; return {}; } diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index eceefdf6..d0c0790b 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -35,8 +35,8 @@ class TestToolchain : public buildcc::Toolchain { private: virtual std::optional VerifySelectedToolchainPath( - const buildcc::ToolchainExecutables &binaries) const override { - (void)binaries; + const buildcc::ToolchainExecutables &executables) const override { + (void)executables; mock().actualCall("VerifySelectedToolchainPath").onObject(this); if (!mock().getData("success").getBoolValue()) { return {}; From 15db5ea26a529acf5dbe380203dddbf1ddde88a2 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 21:01:28 -0700 Subject: [PATCH 25/46] Update args.cpp --- buildcc/lib/args/src/args.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/buildcc/lib/args/src/args.cpp b/buildcc/lib/args/src/args.cpp index 9c95eb5c..e6cd76a1 100644 --- a/buildcc/lib/args/src/args.cpp +++ b/buildcc/lib/args/src/args.cpp @@ -99,16 +99,16 @@ void Args::AddToolchain(const std::string &name, const std::string &description, ->transform(CLI::CheckedTransformer(kToolchainIdMap, CLI::ignore_case)) ->default_val(initial.id); t_user->add_option(kToolchainNameParam, out.name)->default_val(initial.name); - t_user->add_option(kToolchainAsmCompilerParam, out.binaries.assembler) - ->default_val(initial.binaries.assembler); - t_user->add_option(kToolchainCCompilerParam, out.binaries.c_compiler) - ->default_val(initial.binaries.c_compiler); - t_user->add_option(kToolchainCppCompilerParam, out.binaries.cpp_compiler) - ->default_val(initial.binaries.cpp_compiler); - t_user->add_option(kToolchainArchiverParam, out.binaries.archiver) - ->default_val(initial.binaries.archiver); - t_user->add_option(kToolchainLinkerParam, out.binaries.linker) - ->default_val(initial.binaries.linker); + t_user->add_option(kToolchainAsmCompilerParam, out.executables.assembler) + ->default_val(initial.executables.assembler); + t_user->add_option(kToolchainCCompilerParam, out.executables.c_compiler) + ->default_val(initial.executables.c_compiler); + t_user->add_option(kToolchainCppCompilerParam, out.executables.cpp_compiler) + ->default_val(initial.executables.cpp_compiler); + t_user->add_option(kToolchainArchiverParam, out.executables.archiver) + ->default_val(initial.executables.archiver); + t_user->add_option(kToolchainLinkerParam, out.executables.linker) + ->default_val(initial.executables.linker); } void Args::AddTarget(const std::string &name, const std::string &description, From 1a7962d4d03633a99b9f97bbf80efa33fbb753ac Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 21:03:29 -0700 Subject: [PATCH 26/46] Update test_args.cpp --- buildcc/lib/args/test/test_args.cpp | 60 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/buildcc/lib/args/test/test_args.cpp b/buildcc/lib/args/test/test_args.cpp index b52179cf..acaa82b7 100644 --- a/buildcc/lib/args/test/test_args.cpp +++ b/buildcc/lib/args/test/test_args.cpp @@ -68,11 +68,11 @@ TEST(ArgsTestGroup, Args_CustomToolchain) { CHECK_FALSE(gcc_toolchain.state.test); CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.executables.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.executables.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.executables.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.executables.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.executables.linker.c_str(), "ld"); } TEST(ArgsTestGroup, Args_MultipleCustomToolchain) { @@ -106,22 +106,22 @@ TEST(ArgsTestGroup, Args_MultipleCustomToolchain) { CHECK_FALSE(gcc_toolchain.state.test); CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.executables.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.executables.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.executables.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.executables.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.executables.linker.c_str(), "ld"); // MSVC CHECK_TRUE(msvc_toolchain.state.build); CHECK_TRUE(msvc_toolchain.state.test); CHECK(msvc_toolchain.id == buildcc::ToolchainId::Msvc); STRCMP_EQUAL(msvc_toolchain.name.c_str(), "msvc"); - STRCMP_EQUAL(msvc_toolchain.binaries.assembler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.c_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.cpp_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.archiver.c_str(), "lib"); - STRCMP_EQUAL(msvc_toolchain.binaries.linker.c_str(), "link"); + STRCMP_EQUAL(msvc_toolchain.executables.assembler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.c_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.cpp_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.archiver.c_str(), "lib"); + STRCMP_EQUAL(msvc_toolchain.executables.linker.c_str(), "link"); } TEST(ArgsTestGroup, Args_DuplicateCustomToolchain) { @@ -167,11 +167,11 @@ TEST(ArgsTestGroup, Args_CustomTarget) { CHECK_FALSE(gcc_toolchain.state.test); CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.executables.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.executables.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.executables.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.executables.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.executables.linker.c_str(), "ld"); // Target STRCMP_EQUAL(gcc_target.compile_command.c_str(), @@ -221,11 +221,11 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { CHECK_FALSE(gcc_toolchain.state.test); CHECK(gcc_toolchain.id == buildcc::ToolchainId::Gcc); STRCMP_EQUAL(gcc_toolchain.name.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.assembler.c_str(), "as"); - STRCMP_EQUAL(gcc_toolchain.binaries.c_compiler.c_str(), "gcc"); - STRCMP_EQUAL(gcc_toolchain.binaries.cpp_compiler.c_str(), "g++"); - STRCMP_EQUAL(gcc_toolchain.binaries.archiver.c_str(), "ar"); - STRCMP_EQUAL(gcc_toolchain.binaries.linker.c_str(), "ld"); + STRCMP_EQUAL(gcc_toolchain.executables.assembler.c_str(), "as"); + STRCMP_EQUAL(gcc_toolchain.executables.c_compiler.c_str(), "gcc"); + STRCMP_EQUAL(gcc_toolchain.executables.cpp_compiler.c_str(), "g++"); + STRCMP_EQUAL(gcc_toolchain.executables.archiver.c_str(), "ar"); + STRCMP_EQUAL(gcc_toolchain.executables.linker.c_str(), "ld"); // Target STRCMP_EQUAL(gcc_target.compile_command.c_str(), @@ -242,11 +242,11 @@ TEST(ArgsTestGroup, Args_MultipleCustomTarget) { CHECK_TRUE(msvc_toolchain.state.test); CHECK(msvc_toolchain.id == buildcc::ToolchainId::Msvc); STRCMP_EQUAL(msvc_toolchain.name.c_str(), "msvc"); - STRCMP_EQUAL(msvc_toolchain.binaries.assembler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.c_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.cpp_compiler.c_str(), "cl"); - STRCMP_EQUAL(msvc_toolchain.binaries.archiver.c_str(), "lib"); - STRCMP_EQUAL(msvc_toolchain.binaries.linker.c_str(), "link"); + STRCMP_EQUAL(msvc_toolchain.executables.assembler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.c_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.cpp_compiler.c_str(), "cl"); + STRCMP_EQUAL(msvc_toolchain.executables.archiver.c_str(), "lib"); + STRCMP_EQUAL(msvc_toolchain.executables.linker.c_str(), "link"); // Target STRCMP_EQUAL(msvc_target.compile_command.c_str(), From 72234c595238fcd441d750437efcf72a8d9fa8dd Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Mon, 21 Mar 2022 21:10:47 -0700 Subject: [PATCH 27/46] Update toolchain_find.cpp --- buildcc/lib/toolchain/src/api/toolchain_find.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildcc/lib/toolchain/src/api/toolchain_find.cpp b/buildcc/lib/toolchain/src/api/toolchain_find.cpp index 2c4dd8ae..bdef49b3 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_find.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_find.cpp @@ -39,7 +39,7 @@ std::vector ParseEnvVarToPaths(const std::string &env_var) { return paths; } -bool ContainsToolchainBinaries( +bool ContainsToolchainExecutables( const fs::directory_iterator &directory_iterator, const buildcc::ToolchainExecutables &executables) { std::unordered_set exes( @@ -92,7 +92,7 @@ ToolchainFind::Find(const ToolchainFindConfig &config) const { continue; } - bool toolchains_matched = ContainsToolchainBinaries( + bool toolchains_matched = ContainsToolchainExecutables( directory_iterator, t.GetToolchainExecutables()); if (toolchains_matched) { found_toolchains.push_back(search_path); From 92ab70e42177d1912bbef9a5045439bc25036100 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 23 Mar 2022 01:39:12 -0700 Subject: [PATCH 28/46] Added toolchain_executables and toolchain_id header files --- .../toolchain/common/toolchain_executables.h | 41 ++++++++++++ .../include/toolchain/common/toolchain_id.h | 63 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 buildcc/lib/toolchain/include/toolchain/common/toolchain_executables.h create mode 100644 buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h diff --git a/buildcc/lib/toolchain/include/toolchain/common/toolchain_executables.h b/buildcc/lib/toolchain/include/toolchain/common/toolchain_executables.h new file mode 100644 index 00000000..b8862200 --- /dev/null +++ b/buildcc/lib/toolchain/include/toolchain/common/toolchain_executables.h @@ -0,0 +1,41 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAIN_COMMON_TOOLCHAIN_EXECUTABLES_H_ +#define TOOLCHAIN_COMMON_TOOLCHAIN_EXECUTABLES_H_ + +#include +#include + +namespace buildcc { + +struct ToolchainExecutables { + explicit ToolchainExecutables() = default; + explicit ToolchainExecutables(std::string_view as, std::string_view c, + std::string_view cpp, std::string_view ar, + std::string_view link) + : assembler(as), c_compiler(c), cpp_compiler(cpp), archiver(ar), + linker(link) {} + std::string assembler; + std::string c_compiler; + std::string cpp_compiler; + std::string archiver; + std::string linker; +}; + +} // namespace buildcc + +#endif diff --git a/buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h b/buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h new file mode 100644 index 00000000..fa0fc9e1 --- /dev/null +++ b/buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h @@ -0,0 +1,63 @@ +/* + * Copyright 2021-2022 Niket Naidu. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TOOLCHAIN_COMMON_TOOLCHAIN_ID_H_ +#define TOOLCHAIN_COMMON_TOOLCHAIN_ID_H_ + +namespace buildcc { + +enum class ToolchainId { + Gcc = 0, ///< GCC Toolchain + Msvc, ///< MSVC Toolchain + Clang, ///< Clang Toolchain + MinGW, ///< MinGW Toolchain (Similar to GCC, but for Windows) + Custom, ///< Custom Toolchain not defined in this list + Undefined, ///< Default value when unknown +}; + +} // namespace buildcc + +template <> +struct fmt::formatter : formatter { + template + auto format(buildcc::ToolchainId id, FormatContext &ctx) { + std::string id_name; + switch (id) { + case buildcc::ToolchainId::Gcc: + id_name = "Gcc"; + break; + case buildcc::ToolchainId::Msvc: + id_name = "Msvc"; + break; + case buildcc::ToolchainId::Clang: + id_name = "Clang"; + break; + case buildcc::ToolchainId::MinGW: + id_name = "MinGW"; + break; + case buildcc::ToolchainId::Custom: + id_name = "Custom"; + break; + case buildcc::ToolchainId::Undefined: + default: + id_name = "Undefined"; + break; + } + return formatter::format(id_name, ctx); + } +}; + +#endif From ac079bb20dfd271d708f14225f7f5c4dbd266627 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 23 Mar 2022 01:39:43 -0700 Subject: [PATCH 29/46] Updated toolchain.h --- .../toolchain/include/toolchain/toolchain.h | 27 ++----------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/toolchain.h b/buildcc/lib/toolchain/include/toolchain/toolchain.h index 4d5023ea..7ae3e959 100644 --- a/buildcc/lib/toolchain/include/toolchain/toolchain.h +++ b/buildcc/lib/toolchain/include/toolchain/toolchain.h @@ -23,6 +23,8 @@ #include "toolchain/common/function_lock.h" #include "toolchain/common/toolchain_config.h" +#include "toolchain/common/toolchain_executables.h" +#include "toolchain/common/toolchain_id.h" #include "toolchain/api/flag_api.h" #include "toolchain/api/toolchain_find.h" @@ -30,29 +32,6 @@ namespace buildcc { -enum class ToolchainId { - Gcc = 0, ///< GCC Toolchain - Msvc, ///< MSVC Toolchain - Clang, ///< Clang Toolchain - MinGW, ///< MinGW Toolchain (Similar to GCC, but for Windows) - Custom, ///< Custom Toolchain not defined in this list - Undefined, ///< Default value when unknown -}; - -struct ToolchainExecutables { - explicit ToolchainExecutables() = default; - explicit ToolchainExecutables(std::string_view as, std::string_view c, - std::string_view cpp, std::string_view ar, - std::string_view link) - : assembler(as), c_compiler(c), cpp_compiler(cpp), archiver(ar), - linker(link) {} - std::string assembler; - std::string c_compiler; - std::string cpp_compiler; - std::string archiver; - std::string linker; -}; - // Base toolchain class class Toolchain : public internal::FlagApi, public ToolchainFind, @@ -115,8 +94,6 @@ class Toolchain : public internal::FlagApi, void Initialize(); virtual void UpdateConfig(ToolchainConfig &config); - virtual std::optional - VerifySelectedToolchainPath(const ToolchainExecutables &executables) const; private: friend class internal::FlagApi; From aa606f86f0ebde380b0ed550be3093614a20df93 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 23 Mar 2022 01:39:59 -0700 Subject: [PATCH 30/46] Updated toolchain.cpp --- buildcc/lib/toolchain/src/toolchain/toolchain.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp index 00ec0a08..53bee71c 100644 --- a/buildcc/lib/toolchain/src/toolchain/toolchain.cpp +++ b/buildcc/lib/toolchain/src/toolchain/toolchain.cpp @@ -24,10 +24,5 @@ void Toolchain::Lock() { lock_.Lock(); } // PRIVATE void Toolchain::UpdateConfig(ToolchainConfig &config) { (void)config; } -std::optional Toolchain::VerifySelectedToolchainPath( - const ToolchainExecutables &executables) const { - (void)executables; - return {}; -} } // namespace buildcc From f7cfb775e1fe3c5e6cc7808581da17fbc1aa9b35 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 23 Mar 2022 01:42:02 -0700 Subject: [PATCH 31/46] Updated toolchain_verify --- .../include/toolchain/api/toolchain_verify.h | 47 +++- .../toolchain/src/api/toolchain_verify.cpp | 249 ++++++++++++++---- 2 files changed, 244 insertions(+), 52 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index e4de131d..a8733e22 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -25,12 +25,21 @@ #include "env/logging.h" -#include "toolchain_find.h" +#include "toolchain/common/toolchain_executables.h" +#include "toolchain/common/toolchain_id.h" + +#include "toolchain/api/toolchain_find.h" namespace fs = std::filesystem; namespace buildcc { +struct ToolchainVerifyConfig : public ToolchainFindConfig { + ToolchainVerifyConfig() = default; + + std::optional verification_identifier; +}; + /** * @brief Verified Toolchain information * @param path Absolute host path where ALL the toolchain executables are found @@ -40,15 +49,34 @@ namespace buildcc { * @param target_arch Target architecture of the verified toolchain */ struct ToolchainCompilerInfo { + ToolchainCompilerInfo() = default; + std::string ToString() const { return fmt::format("{}", *this); } + fs::path path; std::string compiler_version; std::string target_arch; - - std::string ToString() const { return fmt::format("{}", *this); } }; +typedef std::function( + const ToolchainExecutables &)> + ToolchainVerificationFunc; + template class ToolchainVerify { public: + ToolchainVerify() { Initialize(); } + + /** + * @brief + * + * @param id + * @param verification_func + * @param identifier Only read when ToolchainId::Custom is passed in + */ + static void + AddVerificationFunc(ToolchainId id, + const ToolchainVerificationFunc &verification_func, + const std::optional &op_identifier = {}); + /** * @brief Verify your toolchain executables by searching your operating system * paths @@ -60,10 +88,21 @@ template class ToolchainVerify { * of them */ ToolchainCompilerInfo - Verify(const ToolchainFindConfig &config = ToolchainFindConfig()); + 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() { + static std::unordered_map + verification_func_map; + return verification_func_map; + } }; } // namespace buildcc diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 82dc703e..22a4c4a4 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -33,37 +33,191 @@ #include "toolchain/toolchain.h" +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) { + constexpr const char *const executable_ext = + buildcc::env::get_os_executable_extension(); + buildcc::env::assert_fatal( + "Host executable extension not supported"); + + std::string assembler_path = fmt::format( + "{}", (absolute_path / fmt::format("{}{}", current_executables.assembler, + executable_ext))); + std::string c_compiler_path = fmt::format( + "{}", (absolute_path / fmt::format("{}{}", current_executables.c_compiler, + executable_ext))); + std::string cpp_compiler_path = fmt::format( + "{}", + (absolute_path / + fmt::format("{}{}", current_executables.cpp_compiler, executable_ext))); + std::string archiver_path = fmt::format( + "{}", (absolute_path / fmt::format("{}{}", current_executables.archiver, + executable_ext))); + std::string linker_path = fmt::format( + "{}", (absolute_path / + fmt::format("{}{}", current_executables.linker, executable_ext))); + + return buildcc::ToolchainExecutables(assembler_path, c_compiler_path, + cpp_compiler_path, archiver_path, + linker_path); +} + +std::string +GetToolchainVerifyIdentifier(buildcc::ToolchainId id, + const std::optional &op_identifier) { + std::string identifier; + switch (id) { + case buildcc::ToolchainId::Custom: + buildcc::env::assert_fatal( + op_identifier.has_value(), + "Requires verification_identifier value in ToolchainVerifyConfig"); + identifier = op_identifier.value(); + break; + case buildcc::ToolchainId::Gcc: + case buildcc::ToolchainId::Msvc: + 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 ToolchainFindConfig &config) { +ToolchainVerify::Verify(const ToolchainVerifyConfig &config) { T &t = static_cast(*this); std::vector toolchain_paths = t.Find(config); env::assert_fatal(!toolchain_paths.empty(), "No toolchains found"); - constexpr const char *const executable_ext = - env::get_os_executable_extension(); - env::assert_fatal( - "Host executable extension not supported"); - ToolchainExecutables exes( - fmt::format("{}", (toolchain_paths[0] / - fmt::format("{}{}", t.executables_.assembler, - executable_ext))), - fmt::format("{}", (toolchain_paths[0] / - fmt::format("{}{}", t.executables_.c_compiler, - executable_ext))), - fmt::format("{}", (toolchain_paths[0] / - fmt::format("{}{}", t.executables_.cpp_compiler, - executable_ext))), - fmt::format( - "{}", (toolchain_paths[0] / - fmt::format("{}{}", t.executables_.archiver, executable_ext))), - fmt::format( - "{}", (toolchain_paths[0] / - fmt::format("{}{}", t.executables_.linker, executable_ext)))); - - auto op_toolchain_compiler_info = t.VerifySelectedToolchainPath(exes); + ToolchainExecutables exes = + CreateToolchainExecutables(toolchain_paths[0], t.executables_); + + std::string toolchain_id_identifier = + GetToolchainVerifyIdentifier(t.GetId(), config.verification_identifier); + + const auto &verification_func = + T::GetVerificationFunc(toolchain_id_identifier); + auto op_toolchain_compiler_info = verification_func(exes); env::assert_fatal(op_toolchain_compiler_info.has_value(), "Could not verify toolchain"); @@ -72,34 +226,33 @@ ToolchainVerify::Verify(const ToolchainFindConfig &config) { toolchain_compiler_info.path = toolchain_paths[0]; // Update the compilers - t.executables_.assembler = - (toolchain_compiler_info.path / - fmt::format("{}{}", t.executables_.assembler, executable_ext)) - .make_preferred() - .string(); - t.executables_.c_compiler = - (toolchain_compiler_info.path / - fmt::format("{}{}", t.executables_.c_compiler, executable_ext)) - .make_preferred() - .string(); - t.executables_.cpp_compiler = - (toolchain_compiler_info.path / - fmt::format("{}{}", t.executables_.cpp_compiler, executable_ext)) - .make_preferred() - .string(); - t.executables_.archiver = - (toolchain_compiler_info.path / - fmt::format("{}{}", t.executables_.archiver, executable_ext)) - .make_preferred() - .string(); - t.executables_.linker = - (toolchain_compiler_info.path / - fmt::format("{}{}", t.executables_.linker, executable_ext)) - .make_preferred() - .string(); + t.executables_ = exes; return toolchain_compiler_info; } +// PRIVATE +template void ToolchainVerify::Initialize() { + static bool do_once = true; + + if (do_once) { + do_once = false; + AddVerificationFunc(ToolchainId::Gcc, GccVerificationFunc); + AddVerificationFunc(ToolchainId::Msvc, MsvcVerificationFunc); + AddVerificationFunc(ToolchainId::Clang, GccVerificationFunc); + AddVerificationFunc(ToolchainId::MinGW, GccVerificationFunc); + } +} + +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 class ToolchainVerify; } // namespace buildcc From 455b54e91a34d099586795e004554c5a35c4dab2 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 23 Mar 2022 01:42:22 -0700 Subject: [PATCH 32/46] Updated tests --- .../test/target/test_toolchain_flag_api.cpp | 1 + .../toolchain/test/test_toolchain_find.cpp | 12 +- .../toolchain/test/test_toolchain_verify.cpp | 195 ++++++++++++------ 3 files changed, 129 insertions(+), 79 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 3d698891..dc5aa0f7 100644 --- a/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp +++ b/buildcc/lib/target/test/target/test_toolchain_flag_api.cpp @@ -85,5 +85,6 @@ TEST(ToolchainFlagApiTestGroup, BasicTargetTest) { } int main(int ac, char **av) { + MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/toolchain/test/test_toolchain_find.cpp b/buildcc/lib/toolchain/test/test_toolchain_find.cpp index ee6dcb7f..3867b8ac 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_find.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_find.cpp @@ -97,16 +97,6 @@ TEST(ToolchainFindTestGroup, FindToolchain_NoToolchainFound) { } int main(int ac, char **av) { - // NOTE, Check the GCC, MSVC and Clang compilers - // Create directory and populate it with gcc and cl executables - // Linux - // toolchains/gcc - // toolchains/clang - - // Windows - // toolchains/msvc - // toolchains/mingw - // TODO, Check executables used in clang - + MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); return CommandLineTestRunner::RunAllTests(ac, av); } diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index d0c0790b..0bfe7df7 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -3,7 +3,6 @@ #include "toolchain/toolchain.h" #include "env/host_os.h" -#include "env/host_os_util.h" #include "expect_command.h" @@ -26,105 +25,165 @@ TEST_GROUP(ToolchainVerifyTestGroup) }; // clang-format on -class TestToolchain : public buildcc::Toolchain { -public: - TestToolchain() - : Toolchain(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", - "ld") {} - -private: - virtual std::optional - VerifySelectedToolchainPath( - const buildcc::ToolchainExecutables &executables) const override { - (void)executables; - mock().actualCall("VerifySelectedToolchainPath").onObject(this); - if (!mock().getData("success").getBoolValue()) { - return {}; - } - - buildcc::ToolchainCompilerInfo compiler_info; - compiler_info.path = mock().getData("path").getStringValue(); - compiler_info.target_arch = mock().getData("target_arch").getStringValue(); - compiler_info.compiler_version = - mock().getData("compiler_version").getStringValue(); - return compiler_info; - } -}; - // NOTE, We are mocking the environment instead of actually querying it -TEST(ToolchainVerifyTestGroup, VerifyToolchain_Success) { - TestToolchain gcc; - std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", - fs::current_path().string()); +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + std::vector version_stdout_data{"version"}; + std::vector arch_stdout_data{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); + + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); int put = putenv(putenv_str.data()); CHECK_TRUE(put == 0); const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); CHECK_TRUE(custom_buildcc_path != nullptr); - // UT_PRINT(custom_buildcc_path); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; + config.env_vars.clear(); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + buildcc::ToolchainCompilerInfo compiler_info = gcc.Verify(config); + + STRCMP_EQUAL(compiler_info.compiler_version.c_str(), "version"); + STRCMP_EQUAL(compiler_info.target_arch.c_str(), "arch"); +} + +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Clang) { + buildcc::Toolchain clang(buildcc::ToolchainId::Clang, "clang", "llvm-as", + "clang", "clang++", "llvm-ar", "lld"); - mock().expectOneCall("VerifySelectedToolchainPath").onObject(&gcc); - mock().setData("success", true); - mock().setData("path", "dummy/path"); - mock().setData("compiler_version", "version"); - mock().setData("target_arch", "arch"); + std::vector version_stdout_data{"version"}; + std::vector arch_stdout_data{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); - buildcc::ToolchainFindConfig config; + std::string putenv_str = fmt::format( + "CUSTOM_BUILDCC_PATH={}/toolchains/clang", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); config.env_vars.insert("CUSTOM_BUILDCC_PATH"); - buildcc::ToolchainCompilerInfo verified_toolchain = gcc.Verify(config); - // CHECK_TRUE(!verified_toolchain.empty()); - STRCMP_EQUAL(verified_toolchain.compiler_version.c_str(), "version"); - STRCMP_EQUAL(verified_toolchain.target_arch.c_str(), "arch"); + 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_Failure) { - TestToolchain gcc; - std::string putenv_str = fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", - fs::current_path().string()); +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); - mock().expectOneCall("VerifySelectedToolchainPath").onObject(&gcc); - mock().setData("success", false); - mock().setData("path", "dummy/path"); - mock().setData("compiler_version", "version"); - mock().setData("target_arch", "arch"); + 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"); +} - buildcc::ToolchainFindConfig config; +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_FailureBaseToolchain) { +TEST(ToolchainVerifyTestGroup, VerifyToolchain_BadAbsolutePath) { buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", "ar", "ld"); - { - std::string putenv_str = fmt::format( - "CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path().string()); - int put = putenv(putenv_str.data()); - CHECK_TRUE(put == 0); - const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); - CHECK_TRUE(custom_buildcc_path != nullptr); - UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; + config.env_vars.clear(); + config.absolute_search_paths.insert((fs::current_path() / "does_not_exist")); + + CHECK_THROWS(std::exception, gcc.Verify(config)); +} + +TEST(ToolchainVerifyTestGroup, VerifyToolchain_PathContainsDir) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + buildcc::ToolchainVerifyConfig config; + config.env_vars.clear(); + config.absolute_search_paths.insert((fs::current_path() / "toolchains")); + + CHECK_THROWS(std::exception, gcc.Verify(config)); +} + +#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__MINGW64__) + +TEST(ToolchainVerifyTestGroup, VerifyToolchain_LockedFolder) { + std::error_code err; + fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::none, + err); + if (err) { + FAIL_TEST("Could not set file permissions"); } - // mock().expectOneCall("VerifySelectedToolchainPath").onObject(&gcc); - // mock().setData("success", false); - // mock().setData("path", "dummy/path"); - // mock().setData("compiler_version", "version"); - // mock().setData("target_arch", "arch"); + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); - buildcc::ToolchainFindConfig config; + buildcc::ToolchainVerifyConfig config; config.env_vars.clear(); - config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + config.absolute_search_paths.insert( + (fs::current_path() / "toolchains" / "gcc")); + CHECK_THROWS(std::exception, gcc.Verify(config)); + + fs::permissions(fs::current_path() / "toolchains" / "gcc", fs::perms::all, + err); + if (err) { + FAIL_TEST("Could not set file permissions"); + } } +#endif + int main(int ac, char **av) { buildcc::env::m::VectorStringCopier copier; mock().installCopier(TEST_VECTOR_STRING_TYPE, copier); @@ -139,6 +198,6 @@ int main(int ac, char **av) { // toolchains/msvc // toolchains/mingw // TODO, Check executables used in clang - + MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); return CommandLineTestRunner::RunAllTests(ac, av); } From 79c07f80e6da415c797cb53713f0e11bdab5d0e4 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 23 Mar 2022 01:43:08 -0700 Subject: [PATCH 33/46] Updated specialized_toolchains --- .../include/toolchains/toolchain_gcc.h | 44 ------------------- .../include/toolchains/toolchain_mingw.h | 4 -- .../include/toolchains/toolchain_msvc.h | 36 --------------- 3 files changed, 84 deletions(-) diff --git a/buildcc/toolchains/include/toolchains/toolchain_gcc.h b/buildcc/toolchains/include/toolchains/toolchain_gcc.h index ec21057a..9e54351f 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_gcc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_gcc.h @@ -27,45 +27,6 @@ constexpr const char *const kGccPchCompileExt = ".gch"; constexpr const char *const kGccPrefixIncludeDir = "-I"; constexpr const char *const kGccPrefixLibDir = "-L"; -inline 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]; -} - -inline 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]; -} - -inline std::optional -VerifyGccSelectedToolchainPath(const ToolchainExecutables &executables) { - 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 {}; - } - - ToolchainCompilerInfo compiler_info; - compiler_info.compiler_version = op_compiler_version.value(); - compiler_info.target_arch = op_target_arch.value(); - return compiler_info; -} - /** * @brief Generic GCC Toolchain
* id = ToolchainId::Gcc
@@ -90,11 +51,6 @@ class Toolchain_gcc : public Toolchain { config.prefix_include_dir = kGccPrefixIncludeDir; config.prefix_lib_dir = kGccPrefixLibDir; } - - virtual std::optional - VerifySelectedToolchainPath(const ToolchainExecutables &executables) const { - return VerifyGccSelectedToolchainPath(executables); - } }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_mingw.h b/buildcc/toolchains/include/toolchains/toolchain_mingw.h index f803401d..d0e76824 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_mingw.h +++ b/buildcc/toolchains/include/toolchains/toolchain_mingw.h @@ -53,10 +53,6 @@ class Toolchain_mingw : public BaseToolchain { config.prefix_include_dir = kMingwPrefixIncludeDir; config.prefix_lib_dir = kMingwPrefixLibDir; } - virtual std::optional - VerifySelectedToolchainPath(const ToolchainExecutables &executables) const { - return VerifyGccSelectedToolchainPath(executables); - } }; } // namespace buildcc diff --git a/buildcc/toolchains/include/toolchains/toolchain_msvc.h b/buildcc/toolchains/include/toolchains/toolchain_msvc.h index 0e49565e..db40a8d6 100644 --- a/buildcc/toolchains/include/toolchains/toolchain_msvc.h +++ b/buildcc/toolchains/include/toolchains/toolchain_msvc.h @@ -52,42 +52,6 @@ class Toolchain_msvc : public Toolchain { config.prefix_include_dir = kMsvcPrefixIncludeDir; config.prefix_lib_dir = kMsvcPrefixLibDir; } - - virtual std::optional - VerifySelectedToolchainPath(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 {}; - } - - 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 { - const char *vscmd_version = getenv("VSCMD_VER"); - if (vscmd_version == nullptr) { - return {}; - } - return vscmd_version; - } - - std::optional GetMsvcTargetArchitecture() const { - // 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 buildcc From 490d12c4abc81f01103bda9504164f6bff4fdfa5 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 23 Mar 2022 21:00:59 -0700 Subject: [PATCH 34/46] Update toolchain_verify.cpp --- .../toolchain/src/api/toolchain_verify.cpp | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 22a4c4a4..97633668 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -120,22 +120,26 @@ buildcc::ToolchainExecutables CreateToolchainExecutables( buildcc::env::assert_fatal( "Host executable extension not supported"); - std::string assembler_path = fmt::format( - "{}", (absolute_path / fmt::format("{}{}", current_executables.assembler, - executable_ext))); - std::string c_compiler_path = fmt::format( - "{}", (absolute_path / fmt::format("{}{}", current_executables.c_compiler, - executable_ext))); - std::string cpp_compiler_path = fmt::format( - "{}", + std::string assembler_path = (absolute_path / - fmt::format("{}{}", current_executables.cpp_compiler, executable_ext))); - std::string archiver_path = fmt::format( - "{}", (absolute_path / fmt::format("{}{}", current_executables.archiver, - executable_ext))); - std::string linker_path = fmt::format( - "{}", (absolute_path / - fmt::format("{}{}", current_executables.linker, executable_ext))); + fmt::format("{}{}", current_executables.assembler, executable_ext)) + .string(); + std::string c_compiler_path = + (absolute_path / + fmt::format("{}{}", current_executables.c_compiler, executable_ext)) + .string(); + std::string cpp_compiler_path = + (absolute_path / + fmt::format("{}{}", current_executables.cpp_compiler, executable_ext)) + .string(); + std::string archiver_path = + (absolute_path / + fmt::format("{}{}", current_executables.archiver, executable_ext)) + .string(); + std::string linker_path = + (absolute_path / + fmt::format("{}{}", current_executables.linker, executable_ext)) + .string(); return buildcc::ToolchainExecutables(assembler_path, c_compiler_path, cpp_compiler_path, archiver_path, From da33d91596de2978318d596b069ccfb4dfc2e3ec Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 23 Mar 2022 21:10:13 -0700 Subject: [PATCH 35/46] Updated buildexe with toolchain.Verify --- buildexe/buildexe.cpp | 3 ++- buildexe/include/buildexe/toolchain_setup.h | 1 - buildexe/src/toolchain_setup.cpp | 4 ---- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/buildexe/buildexe.cpp b/buildexe/buildexe.cpp index faa7ede4..5b0cc000 100644 --- a/buildexe/buildexe.cpp +++ b/buildexe/buildexe.cpp @@ -60,7 +60,8 @@ int main(int argc, char **argv) { // Host Toolchain BaseToolchain toolchain = buildexe_args.GetHostToolchainArg().ConstructToolchain(); - find_toolchain_verify(toolchain); + toolchain.Verify(); + if (buildexe_args.GetBuildMode() == BuildExeMode::Script) { host_toolchain_verify(toolchain); } diff --git a/buildexe/include/buildexe/toolchain_setup.h b/buildexe/include/buildexe/toolchain_setup.h index 423bbbf4..2f87b9f3 100644 --- a/buildexe/include/buildexe/toolchain_setup.h +++ b/buildexe/include/buildexe/toolchain_setup.h @@ -21,7 +21,6 @@ namespace buildcc { -void find_toolchain_verify(BaseToolchain &toolchain); void host_toolchain_verify(const BaseToolchain &toolchain); } // namespace buildcc diff --git a/buildexe/src/toolchain_setup.cpp b/buildexe/src/toolchain_setup.cpp index ddb331f0..b007f51b 100644 --- a/buildexe/src/toolchain_setup.cpp +++ b/buildexe/src/toolchain_setup.cpp @@ -24,10 +24,6 @@ constexpr const char *const kTag = "BuildExe"; namespace buildcc { -void find_toolchain_verify(BaseToolchain &toolchain) { - (void)toolchain.Verify(); -} - void host_toolchain_verify(const BaseToolchain &toolchain) { env::log_info(kTag, "*** Starting Toolchain verification ***"); From 1030886ca1cbdf6ca7ae7399976804bc48bea8af Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 23 Mar 2022 21:31:27 -0700 Subject: [PATCH 36/46] Update toolchain_id.h --- buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h b/buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h index fa0fc9e1..d19ea6d6 100644 --- a/buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h +++ b/buildcc/lib/toolchain/include/toolchain/common/toolchain_id.h @@ -17,6 +17,8 @@ #ifndef TOOLCHAIN_COMMON_TOOLCHAIN_ID_H_ #define TOOLCHAIN_COMMON_TOOLCHAIN_ID_H_ +#include "fmt/format.h" + namespace buildcc { enum class ToolchainId { From 75e78132933f78746867c31b7f3aeed8402d130f Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Wed, 23 Mar 2022 21:31:44 -0700 Subject: [PATCH 37/46] Added test_toolchain_id --- buildcc/lib/toolchain/CMakeLists.txt | 9 +++- .../lib/toolchain/test/test_toolchain_id.cpp | 50 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 buildcc/lib/toolchain/test/test_toolchain_id.cpp diff --git a/buildcc/lib/toolchain/CMakeLists.txt b/buildcc/lib/toolchain/CMakeLists.txt index 60ed092d..ce4f6ac0 100644 --- a/buildcc/lib/toolchain/CMakeLists.txt +++ b/buildcc/lib/toolchain/CMakeLists.txt @@ -32,6 +32,13 @@ if (${TESTING}) ${TEST_LINK_LIBS} ) + add_executable(test_toolchain_id + test/test_toolchain_id.cpp + ) + target_link_libraries(test_toolchain_id PRIVATE + mock_toolchain + ) + add_executable(test_toolchain_config test/test_toolchain_config.cpp ) @@ -53,7 +60,7 @@ if (${TESTING}) mock_toolchain ) - + add_test(NAME test_toolchain_id COMMAND test_toolchain_id) add_test(NAME test_toolchain_config COMMAND test_toolchain_config) add_test(NAME test_toolchain_find COMMAND test_toolchain_find WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test diff --git a/buildcc/lib/toolchain/test/test_toolchain_id.cpp b/buildcc/lib/toolchain/test/test_toolchain_id.cpp new file mode 100644 index 00000000..6cb77e6b --- /dev/null +++ b/buildcc/lib/toolchain/test/test_toolchain_id.cpp @@ -0,0 +1,50 @@ +#include + +#include "toolchain/common/toolchain_id.h" + +// NOTE, Make sure all these includes are AFTER the system and header includes +#include "CppUTest/CommandLineTestRunner.h" +#include "CppUTest/MemoryLeakDetectorNewMacros.h" +#include "CppUTest/TestHarness.h" +#include "CppUTest/Utest.h" +#include "CppUTestExt/MockSupport.h" + +// clang-format off +TEST_GROUP(ToolchainIdTestGroup) +{ + void teardown() { + mock().checkExpectations(); + mock().clear(); + } +}; +// clang-format on + +TEST(ToolchainIdTestGroup, ToolchainIdAsString) { + std::string compiler; + + compiler = fmt::format("{}", buildcc::ToolchainId::Gcc); + STRCMP_EQUAL(compiler.c_str(), "Gcc"); + + compiler = fmt::format("{}", buildcc::ToolchainId::Msvc); + STRCMP_EQUAL(compiler.c_str(), "Msvc"); + + compiler = fmt::format("{}", buildcc::ToolchainId::Clang); + STRCMP_EQUAL(compiler.c_str(), "Clang"); + + compiler = fmt::format("{}", buildcc::ToolchainId::MinGW); + STRCMP_EQUAL(compiler.c_str(), "MinGW"); + + compiler = fmt::format("{}", buildcc::ToolchainId::Custom); + STRCMP_EQUAL(compiler.c_str(), "Custom"); + + compiler = fmt::format("{}", buildcc::ToolchainId::Undefined); + STRCMP_EQUAL(compiler.c_str(), "Undefined"); + + compiler = fmt::format("{}", (buildcc::ToolchainId)65535); + STRCMP_EQUAL(compiler.c_str(), "Undefined"); +} + +int main(int ac, char **av) { + MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); + return CommandLineTestRunner::RunAllTests(ac, av); +} From 5e972cb74b0f8d55ec974a55455537c986a6a47e Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Mar 2022 02:12:53 -0700 Subject: [PATCH 38/46] Update test_toolchain_verify.cpp --- .../toolchain/test/test_toolchain_verify.cpp | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 0bfe7df7..5129fa18 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -53,6 +53,54 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc) { STRCMP_EQUAL(compiler_info.target_arch.c_str(), "arch"); } +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionFailure) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + std::vector version_stdout_data{"version"}; + std::vector arch_stdout_data{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, false, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); + + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; + config.env_vars.clear(); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + CHECK_THROWS(std::exception, gcc.Verify(config)); +} + +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionEmpty) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + std::vector version_stdout_data; + std::vector arch_stdout_data{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); + + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; + config.env_vars.clear(); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + CHECK_THROWS(std::exception, gcc.Verify(config)); +} + TEST(ToolchainVerifyTestGroup, VerifyToolchain_Clang) { buildcc::Toolchain clang(buildcc::ToolchainId::Clang, "clang", "llvm-as", "clang", "clang++", "llvm-ar", "lld"); From 74e80604ecadce42cfa06cfc0f9a5e6b8b34cbe2 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Mar 2022 02:13:00 -0700 Subject: [PATCH 39/46] Update toolchain_verify.cpp --- buildcc/lib/toolchain/src/api/toolchain_verify.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index 97633668..afcc7837 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -51,7 +51,7 @@ 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()) { + if (!executed || stdout_data.empty()) { return {}; } return stdout_data[0]; From f05e41564bbeea6c0c0d0e36601e2fd7929638a7 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Mar 2022 03:25:09 -0700 Subject: [PATCH 40/46] Update test_toolchain_verify.cpp --- .../toolchain/test/test_toolchain_verify.cpp | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 5129fa18..b551c3c9 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -101,6 +101,54 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_CompilerVersionEmpty) { CHECK_THROWS(std::exception, gcc.Verify(config)); } +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchFailure) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + std::vector version_stdout_data{"version"}; + std::vector arch_stdout_data{"arch"}; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, false, &arch_stdout_data); + + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; + config.env_vars.clear(); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + CHECK_THROWS(std::exception, gcc.Verify(config)); +} + +TEST(ToolchainVerifyTestGroup, VerifyToolchain_Gcc_TargetArchEmpty) { + buildcc::Toolchain gcc(buildcc::ToolchainId::Gcc, "gcc", "as", "gcc", "g++", + "ar", "ld"); + + std::vector version_stdout_data{"version"}; + std::vector arch_stdout_data; + buildcc::env::m::CommandExpect_Execute(1, true, &version_stdout_data); + buildcc::env::m::CommandExpect_Execute(1, true, &arch_stdout_data); + + std::string putenv_str = + fmt::format("CUSTOM_BUILDCC_PATH={}/toolchains/gcc", fs::current_path()); + int put = putenv(putenv_str.data()); + CHECK_TRUE(put == 0); + const char *custom_buildcc_path = getenv("CUSTOM_BUILDCC_PATH"); + CHECK_TRUE(custom_buildcc_path != nullptr); + UT_PRINT(custom_buildcc_path); + + buildcc::ToolchainVerifyConfig config; + config.env_vars.clear(); + config.env_vars.insert("CUSTOM_BUILDCC_PATH"); + + CHECK_THROWS(std::exception, gcc.Verify(config)); +} + TEST(ToolchainVerifyTestGroup, VerifyToolchain_Clang) { buildcc::Toolchain clang(buildcc::ToolchainId::Clang, "clang", "llvm-as", "clang", "clang++", "llvm-ar", "lld"); From 6fb51b21d80b7c7c52575abdcd686122a659cd9f Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Mar 2022 03:59:57 -0700 Subject: [PATCH 41/46] Update test_toolchain_verify.cpp --- .../toolchain/test/test_toolchain_verify.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index b551c3c9..dd674336 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -210,6 +210,38 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Msvc) { STRCMP_EQUAL(compiler_info.target_arch.c_str(), "host_arch_tgt_arch"); } +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_BadCompilerId) { buildcc::Toolchain gcc((buildcc::ToolchainId)65535, "gcc", "as", "gcc", "g++", "ar", "ld"); From eaa57fd09dd11b9b883428512ed0613d8981c50e Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Mar 2022 04:28:51 -0700 Subject: [PATCH 42/46] Updated test_toolchain_verify for custom toolchains --- .../toolchain/test/test_toolchain_verify.cpp | 64 +++++++++++++++++++ .../toolchain/test/toolchains/custom/archiver | 0 .../test/toolchains/custom/archiver.exe | 0 .../test/toolchains/custom/assembler | 0 .../test/toolchains/custom/assembler.exe | 0 .../test/toolchains/custom/c_compiler | 0 .../test/toolchains/custom/c_compiler.exe | 0 .../test/toolchains/custom/cpp_compiler | 0 .../test/toolchains/custom/cpp_compiler.exe | 0 .../toolchain/test/toolchains/custom/linker | 0 .../test/toolchains/custom/linker.exe | 0 11 files changed, 64 insertions(+) create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/archiver create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/archiver.exe create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/assembler create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/assembler.exe create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/c_compiler create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/c_compiler.exe create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler.exe create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/linker create mode 100644 buildcc/lib/toolchain/test/toolchains/custom/linker.exe diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index dd674336..17da0d32 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -210,6 +210,70 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Msvc) { 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_Msvc_CompilerVersionAndTargetArchFailure) { buildcc::Toolchain msvc(buildcc::ToolchainId::Msvc, "msvc", "cl", "cl", "cl", diff --git a/buildcc/lib/toolchain/test/toolchains/custom/archiver b/buildcc/lib/toolchain/test/toolchains/custom/archiver new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/archiver.exe b/buildcc/lib/toolchain/test/toolchains/custom/archiver.exe new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/assembler b/buildcc/lib/toolchain/test/toolchains/custom/assembler new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/assembler.exe b/buildcc/lib/toolchain/test/toolchains/custom/assembler.exe new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/c_compiler b/buildcc/lib/toolchain/test/toolchains/custom/c_compiler new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/c_compiler.exe b/buildcc/lib/toolchain/test/toolchains/custom/c_compiler.exe new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler b/buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler.exe b/buildcc/lib/toolchain/test/toolchains/custom/cpp_compiler.exe new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/linker b/buildcc/lib/toolchain/test/toolchains/custom/linker new file mode 100644 index 00000000..e69de29b diff --git a/buildcc/lib/toolchain/test/toolchains/custom/linker.exe b/buildcc/lib/toolchain/test/toolchains/custom/linker.exe new file mode 100644 index 00000000..e69de29b From c566b8ea16fdbe7ea35bcf574a1597c352048597 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Mar 2022 04:33:44 -0700 Subject: [PATCH 43/46] Update test_toolchain_verify.cpp --- buildcc/lib/toolchain/test/test_toolchain_verify.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index 17da0d32..af05fdd9 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -274,6 +274,18 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Custom_VerificationFailure) { 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_Msvc_CompilerVersionAndTargetArchFailure) { buildcc::Toolchain msvc(buildcc::ToolchainId::Msvc, "msvc", "cl", "cl", "cl", From b0eff945f29f74086b5ea50ab62f5fe4191e0b24 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Mar 2022 05:12:56 -0700 Subject: [PATCH 44/46] Update toolchain_verify.h --- buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index a8733e22..dbb8548e 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -35,8 +35,6 @@ namespace fs = std::filesystem; namespace buildcc { struct ToolchainVerifyConfig : public ToolchainFindConfig { - ToolchainVerifyConfig() = default; - std::optional verification_identifier; }; @@ -49,7 +47,6 @@ struct ToolchainVerifyConfig : public ToolchainFindConfig { * @param target_arch Target architecture of the verified toolchain */ struct ToolchainCompilerInfo { - ToolchainCompilerInfo() = default; std::string ToString() const { return fmt::format("{}", *this); } fs::path path; From 3db102acf73df31b6340e4ad49dc1954564bb139 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Mar 2022 05:23:55 -0700 Subject: [PATCH 45/46] Update test_toolchain_verify.cpp --- .../toolchain/test/test_toolchain_verify.cpp | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp index af05fdd9..5854191d 100644 --- a/buildcc/lib/toolchain/test/test_toolchain_verify.cpp +++ b/buildcc/lib/toolchain/test/test_toolchain_verify.cpp @@ -286,38 +286,6 @@ TEST(ToolchainVerifyTestGroup, VerifyToolchain_Undefined_AddVerificationFunc) { "undefined_verification_func"))); } -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_BadCompilerId) { buildcc::Toolchain gcc((buildcc::ToolchainId)65535, "gcc", "as", "gcc", "g++", "ar", "ld"); @@ -361,6 +329,38 @@ 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, From 2eaaec9d97898f3949fb671b5635c05f6d2f7b75 Mon Sep 17 00:00:00 2001 From: Niket Naidu Date: Thu, 24 Mar 2022 05:31:10 -0700 Subject: [PATCH 46/46] Updated GetStatic function --- .../toolchain/include/toolchain/api/toolchain_verify.h | 6 +----- buildcc/lib/toolchain/src/api/toolchain_verify.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h index dbb8548e..1318aefd 100644 --- a/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h +++ b/buildcc/lib/toolchain/include/toolchain/api/toolchain_verify.h @@ -95,11 +95,7 @@ template class ToolchainVerify { static const ToolchainVerificationFunc & GetVerificationFunc(const std::string &identifier); static std::unordered_map & - GetStatic() { - static std::unordered_map - verification_func_map; - return verification_func_map; - } + GetStatic(); }; } // namespace buildcc diff --git a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp index afcc7837..1d60b80f 100644 --- a/buildcc/lib/toolchain/src/api/toolchain_verify.cpp +++ b/buildcc/lib/toolchain/src/api/toolchain_verify.cpp @@ -257,6 +257,14 @@ ToolchainVerify::GetVerificationFunc(const std::string &identifier) { 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