#include #include #include #include using namespace std::string_literals; namespace { std::ostream& operator<<(std::ostream& stream, const ToolChain& tool_chain) { switch(tool_chain) { case ToolChain::gcc: stream << "ToolChain::gcc"; break; case ToolChain::clang: stream << "ToolChain::clang"; break; } return stream; } std::ostream& operator<<(std::ostream& stream, const std::vector& vs) { bool first{true}; stream << "{ "; for(const auto& v : vs) { if(!first) { stream << ", "; } stream << "'" << v << "'"; first = false; } stream << " }"; return stream; } std::ostream& operator<<(std::ostream& stream, opt o) { // Adding to this enum should also imply adding to the unit-tests below switch(o) { case opt::output: stream << "opt::output"; break; case opt::debug: stream << "opt::debug"; break; case opt::strip: stream << "opt::strip"; break; case opt::warn_all: stream << "opt::warn_all"; break; case opt::warnings_as_errors: stream << "opt::warnings_as_errors"; break; case opt::generate_dep_tree: stream << "opt::generate_dep_tree"; break; case opt::no_link: stream << "opt::no_link"; break; case opt::include_path: stream << "opt::include_path"; break; case opt::library_path: stream << "opt::library_path"; break; case opt::link: stream << "opt::link"; break; case opt::cpp_std: stream << "opt::cpp_std"; break; case opt::build_shared: stream << "opt::build_shared"; break; case opt::threads: stream << "opt::threads"; break; case opt::optimization: stream << "opt::optimization"; break; case opt::position_independent_code: stream << "opt::position_independent_code"; break; case opt::position_independent_executable: stream << "opt::position_independent_executable"; break; case opt::custom: stream << "opt::custom"; break; } return stream; } std::ostream& operator<<(std::ostream& stream, const std::pair& vs) { stream << "{ " << vs.first << ", " << vs.second << " }"; return stream; } } // Controllable getConfiguration stub: namespace { std::string conf_host_cxx{}; std::string conf_build_cxx{}; } const std::string& getConfiguration(const std::string& key, const std::string& defval) { if(key == cfg::host_cxx) { return conf_host_cxx; } if(key == cfg::build_cxx) { return conf_build_cxx; } assert(false); // bad key static std::string res{}; return res; } class ToolsTest : public uUnit { public: ToolsTest() { uTEST(ToolsTest::getToolChain_test); uTEST(ToolsTest::getOption_toolchain_test); uTEST(ToolsTest::getOption_str_test); } void getToolChain_test() { // host conf_host_cxx = "/usr/bin/g++"; uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Host)); conf_host_cxx = "/usr/bin/g++-10"; uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Host)); conf_host_cxx = "/usr/bin/x86_64-pc-linux-gnu-g++-9.3.0"; uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Host)); conf_host_cxx = "/usr/bin/clang++"; uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Host)); conf_host_cxx = "/usr/bin/clang++-10"; uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Host)); conf_host_cxx = "/usr/lib/llvm/12/bin/i686-pc-linux-gnu-clang++-12"; uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Host)); // build conf_build_cxx = "/usr/bin/g++"; uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Build)); conf_build_cxx = "/usr/bin/g++-10"; uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Build)); conf_build_cxx = "/usr/bin/x86_64-pc-linux-gnu-g++-9.3.0"; uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Build)); conf_build_cxx = "/usr/bin/clang++"; uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Build)); conf_build_cxx = "/usr/bin/clang++-10"; uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Build)); conf_build_cxx = "/usr/lib/llvm/12/bin/i686-pc-linux-gnu-clang++-12"; uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Build)); } void getOption_toolchain_test() { using sv = std::vector; uUnit::assert_equal(sv{ "-o", "foo" }, getOption(ToolChain::clang, opt::output, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-g" }, getOption(ToolChain::clang, opt::debug), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-s" }, getOption(ToolChain::clang, opt::strip), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-Wall" }, getOption(ToolChain::clang, opt::warn_all), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-Werror" }, getOption(ToolChain::clang, opt::warnings_as_errors), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-MMD" }, getOption(ToolChain::clang, opt::generate_dep_tree), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-c" }, getOption(ToolChain::clang, opt::no_link), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-Ifoo" }, getOption(ToolChain::clang, opt::include_path, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-Lfoo" }, getOption(ToolChain::clang, opt::library_path, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-lfoo" }, getOption(ToolChain::clang, opt::link, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-std=foo" }, getOption(ToolChain::clang, opt::cpp_std, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-shared" }, getOption(ToolChain::clang, opt::build_shared), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-pthread" }, getOption(ToolChain::clang, opt::threads), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-Ofoo" }, getOption(ToolChain::clang, opt::optimization, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-fPIC" }, getOption(ToolChain::clang, opt::position_independent_code), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-fPIE" }, getOption(ToolChain::clang, opt::position_independent_executable), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-foo" }, getOption(ToolChain::clang, opt::custom, "-foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-o", "foo" }, getOption(ToolChain::gcc, opt::output, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-g" }, getOption(ToolChain::gcc, opt::debug), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-s" }, getOption(ToolChain::gcc, opt::strip), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-Wall" }, getOption(ToolChain::gcc, opt::warn_all), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-Werror" }, getOption(ToolChain::gcc, opt::warnings_as_errors), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-MMD" }, getOption(ToolChain::gcc, opt::generate_dep_tree), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-c" }, getOption(ToolChain::gcc, opt::no_link), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-Ifoo" }, getOption(ToolChain::gcc, opt::include_path, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-Lfoo" }, getOption(ToolChain::gcc, opt::library_path, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-lfoo" }, getOption(ToolChain::gcc, opt::link, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-std=foo" }, getOption(ToolChain::gcc, opt::cpp_std, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-shared" }, getOption(ToolChain::gcc, opt::build_shared), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-pthread" }, getOption(ToolChain::gcc, opt::threads), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-Ofoo" }, getOption(ToolChain::gcc, opt::optimization, "foo"), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-fPIC" }, getOption(ToolChain::gcc, opt::position_independent_code), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-fPIE" }, getOption(ToolChain::gcc, opt::position_independent_executable), __FILE__, __LINE__); uUnit::assert_equal(sv{ "-foo" }, getOption(ToolChain::gcc, opt::custom, "-foo"), __FILE__, __LINE__); } void getOption_str_test() { using p = std::pair; uUnit::assert_equal(p{ opt::include_path, "foo" }, getOption("-Ifoo", ToolChain::gcc), __FILE__, __LINE__); uUnit::assert_equal(p{ opt::library_path, "foo" }, getOption("-Lfoo", ToolChain::gcc), __FILE__, __LINE__); uUnit::assert_equal(p{ opt::include_path, "foo" }, getOption("-Ifoo", ToolChain::clang), __FILE__, __LINE__); uUnit::assert_equal(p{ opt::library_path, "foo" }, getOption("-Lfoo", ToolChain::clang), __FILE__, __LINE__); } }; // Registers the fixture into the 'registry' static ToolsTest test;