#include "LanguageSettings.h" #include #include #include #include #include #include #include namespace fs = std::filesystem; namespace { std::string env_value(const std::string& key) { char* value_ptr{std::getenv(key.c_str())}; if (value_ptr == nullptr) { return {}; } else { return value_ptr; } } // returns "" if not found std::string find_executable(const std::vector& list) { std::vector paths {Reichwein::Stringhelper::split(env_value("PATH"), ":")}; for (const auto& i: list) { for (const auto& j: paths) { if (fs::exists(j + "/" + i)) { return i; } } } return {}; } } LanguageSettings::LanguageSettings(): // C++ CXX{env_value("CXX")}, CXXFLAGS{env_value("CXXFLAGS")}, LDFLAGS{env_value("LDFLAGS")}, LDLIBS{env_value("LDLIBS")}, LIBS{env_value("LIBS")} // C // CFLAGS { std::string _default_compiler(find_executable({"g++", "clang++"})); if (_default_compiler.empty()) { throw std::runtime_error("No default C++ compiler found."); } // set defaults if (CXX.empty()) { CXX = _default_compiler; } if (CXXFLAGS.empty()) { CXXFLAGS = "-std=c++17"; } } std::string LanguageSettings::getCompileCommand(const std::filesystem::path& target, const std::filesystem::path &source) const { // compile: $(CXX) $(CXXFLAGS) -c $< -o $@ return fmt::format("{} {} -c {} -o {}", CXX, CXXFLAGS, source.string(), target.string()); } std::string LanguageSettings::getLinkCommand(const std::filesystem::path& target, const std::vector &inputs, const std::vector& link_libs) const { // link: $(CXX) $(LDFLAGS) $^ $(LDLIBS) $(LIBS) -o $@ std::string input_string; for (const auto& i: inputs) { if (!input_string.empty()) { input_string += " "; } input_string += i.string(); } std::string link_libs_string; for (const auto& i: link_libs) { if (!link_libs_string.empty()) { link_libs_string += " "; } link_libs_string += "-l" + i; } return fmt::format("{} {} {} {} {} {} -o {}", CXX, CXXFLAGS, input_string, LDLIBS, LIBS, link_libs_string, target.string()); } std::string LanguageSettings::getDepCommand(const std::filesystem::path& target, const std::filesystem::path &source) const { // g++ -MM -MF -c return fmt::format("{} -MM -MF {} -c {}", CXX, target.string(), source.string()); }