#include "LanguageSettings.h" #include #include #include #include #include #include #include #include #include namespace fs = std::filesystem; using namespace std::string_literals; 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 std::vector& includepaths) const { std::string includes{std::accumulate(includepaths.begin(), includepaths.end(), std::string{}, [](const std::string& sum, const fs::path& p){ return sum + " " + p.string();})}; // compile: $(CXX) $(CXXFLAGS) -c $< -o $@ return fmt::format("{}{}{} -c {} -o {}", CXX, CXXFLAGS.empty() ? ""s : (" "s + CXXFLAGS), includes, 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{std::accumulate(inputs.begin(), inputs.end(), std::string{}, [](const std::string& sum, const fs::path& p){ return sum + " " + p.string(); })}; std::string link_libs_string{std::accumulate(link_libs.begin(), link_libs.end(), std::string(), [](const std::string& sum, const std::string& i){ return sum + " -l" + i; })}; return fmt::format("{}{}{}{}{}{} -o {}", CXX, CXXFLAGS.empty() ? ""s : (" "s + CXXFLAGS), input_string, LDLIBS.empty() ? ""s : (" "s + LDLIBS), LIBS.empty() ? ""s : (" "s + 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()); }