diff --git a/mob.ini b/mob.ini index 0e3fa88..bf21190 100644 --- a/mob.ini +++ b/mob.ini @@ -13,6 +13,9 @@ log_file = mob.log ignore_uncommitted = false github_key = +[cmake] +install_message = never + [aliases] super = cmake_common modorganizer* githubpp plugins = check_fnis bsapacker bsa_extractor diagnose_basic installer_* plugin_python preview_base preview_bsa tool_* game_* diff --git a/src/core/conf.cpp b/src/core/conf.cpp index 6c92fdf..4c7d4d2 100644 --- a/src/core/conf.cpp +++ b/src/core/conf.cpp @@ -663,6 +663,11 @@ conf_task conf::task(const std::vector& names) return {names}; } +conf_cmake conf::cmake() +{ + return {}; +} + conf_tools conf::tool() { return {}; @@ -726,6 +731,47 @@ bool conf_task::get_bool(std::string_view key) const } +bool conf_cmake::cmake_constant::is_equivalent(std::string_view other) const +{ + // _strcmpi does not have a n-overload, and since string_view is not + // necessarily null-terminated, _strmcpi cannot be safely used + return std::equal( + std::begin(value_), std::end(value_), + std::begin(other), std::end(other), + [](auto&& c1, auto&& c2) { return ::tolower(c1) == ::tolower(c2); } + ); +} + +conf_cmake::conf_cmake() + : conf_section("cmake") +{ +} + +const conf_cmake::cmake_constant conf_cmake::ALWAYS{"always"}; +const conf_cmake::cmake_constant conf_cmake::LAZY{"lazy"}; +const conf_cmake::cmake_constant conf_cmake::NEVER{"never"}; + +conf_cmake::cmake_constant conf_cmake::install_message() const +{ + return read_cmake_constant("install_message", { ALWAYS, LAZY, NEVER }); +} + +conf_cmake::cmake_constant conf_cmake::read_cmake_constant( + std::string_view key, std::vector const& allowed) const +{ + const auto value = details::get_string(name(), key); + for (const auto& constant : allowed) + { + if (constant.is_equivalent(value)) { + return constant; + } + } + + gcx().bail_out(context::conf, + "bad value '{}' for {}/{} (expected one of {})", + value, name(), key, join(allowed, ", ", std::string{})); +} + conf_tools::conf_tools() : conf_section("tools") { diff --git a/src/core/conf.h b/src/core/conf.h index 5b8d4bc..2090018 100644 --- a/src/core/conf.h +++ b/src/core/conf.h @@ -83,6 +83,8 @@ protected: { } + const auto& name() const { return name_; } + private: std::string name_; }; @@ -151,6 +153,53 @@ private: }; +// options in [task] or [task_name:task] +// +class conf_cmake : conf_section +{ +public: + class cmake_constant { + std::string value_; + + // check if the given string is equivalent to this constant + // + bool is_equivalent(std::string_view other) const; + + friend class conf_cmake; + + public: + constexpr cmake_constant(std::string_view value) : value_{value} { } + constexpr const auto& value() const { return value_; } + constexpr operator const std::string& () const { return value(); } + + + friend bool operator==(cmake_constant const& lhs, cmake_constant const& rhs) + { + return lhs.is_equivalent(rhs.value()); + } + friend bool operator!=(cmake_constant const& lhs, cmake_constant const& rhs) + { + return !(lhs == rhs); + } + + }; + + static const cmake_constant ALWAYS; + static const cmake_constant LAZY; + static const cmake_constant NEVER; + + +public: + conf_cmake(); + + cmake_constant install_message() const; + +private: + cmake_constant read_cmake_constant( + std::string_view key, std::vector const& allowed) const; +}; + + // options in [tools] // class conf_tools : public conf_section @@ -238,6 +287,7 @@ class conf public: conf_global global(); conf_task task(const std::vector& names); + conf_cmake cmake(); conf_tools tool(); conf_transifex transifex(); conf_prebuilt prebuilt(); diff --git a/src/tools/cmake.cpp b/src/tools/cmake.cpp index 5fe25a4..d7e0f2a 100644 --- a/src/tools/cmake.cpp +++ b/src/tools/cmake.cpp @@ -134,7 +134,7 @@ void cmake::do_generate() .stderr_encoding(encodings::utf8) .binary(binary()) .arg("-DCMAKE_BUILD_TYPE=Release") - .arg("-DCMAKE_INSTALL_MESSAGE=NEVER") + .arg("-DCMAKE_INSTALL_MESSAGE=" + conf().cmake().install_message().value()) .arg("--log-level=ERROR") .arg("--no-warn-unused-cli"); diff --git a/src/utility/string.h b/src/utility/string.h index bfb6ab3..041978f 100644 --- a/src/utility/string.h +++ b/src/utility/string.h @@ -22,22 +22,21 @@ std::string replace_all( // concatenates all elements of `v`, separated by `sep` // -template -T join(const std::vector& v, const Sep& sep) +template +auto join(const std::vector& v, const Sep& sep, To prefix = {}) { - T s; bool first = true; for (auto&& e : v) { if (!first) - s += sep; + prefix += sep; - s += e; + prefix += e; first = false; } - return s; + return prefix; } // splits the given string on any character in `seps`