summaryrefslogtreecommitdiffhomepage
path: root/LanguageSettings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'LanguageSettings.cpp')
-rw-r--r--LanguageSettings.cpp104
1 files changed, 104 insertions, 0 deletions
diff --git a/LanguageSettings.cpp b/LanguageSettings.cpp
new file mode 100644
index 0000000..3ded5cf
--- /dev/null
+++ b/LanguageSettings.cpp
@@ -0,0 +1,104 @@
+#include "LanguageSettings.h"
+
+#include <cstdlib>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#include <fmt/format.h>
+
+#include <libreichwein/stringhelper.h>
+
+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<std::string>& list) {
+ std::vector<std::string> 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<std::filesystem::path> &inputs,
+ const std::vector<std::string>& 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 <depfile> -c <cppfile>
+ return fmt::format("{} -MM -MF {} -c {}", CXX, target.string(), source.string());
+}
+