Skip to content

Commit

Permalink
More flexibility to build Debug components (#136)
Browse files Browse the repository at this point in the history
* Build components in all variant for boost to avoid issue with USVFS.
* Build googletest in both Debug and Release.
* Allow build configurations other than RelWithDebInfo.
  • Loading branch information
Holt59 authored Jun 15, 2024
1 parent d1965ac commit ecd210d
Show file tree
Hide file tree
Showing 20 changed files with 423 additions and 193 deletions.
21 changes: 13 additions & 8 deletions mob.ini
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ super = cmake_common modorganizer* githubpp
plugins = check_fnis bsapacker bsa_extractor diagnose_basic installer_* plugin_python preview_base preview_bsa tool_* game_*

[task]
enabled = true
mo_org = ModOrganizer2
mo_branch = master
mo_fallback =
no_pull = false
ignore_ts = false
revert_ts = false
enabled = true
mo_org = ModOrganizer2
mo_branch = master
mo_fallback =
no_pull = false
ignore_ts = false
revert_ts = false
configuration = RelWithDebInfo

git_url_prefix = https://github.com/
git_shallow = true
Expand Down Expand Up @@ -118,7 +119,6 @@ zlib = v1.3.1
libbsarch = 0.0.9
usvfs = master
explorerpp = 1.4.0

ss_paper_lad_6788 = 7.2
ss_paper_automata_6788 = 3.2
ss_paper_mono_6788 = 3.2
Expand All @@ -129,6 +129,11 @@ ss_starfield_trosski = V1.11
ss_fallout3_trosski = v1.11
ss_fallout4_trosski = v1.11

[build-types]
libbsarch = release
pyqt = release
python = release

[paths]
third_party =
prefix =
Expand Down
9 changes: 5 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ aqt install-qt --outputdir "C:\Qt" windows desktop 6.7.0 win64_msvc2019_64 -m qt
- Optional:
- Qt Source Files
- Qt Debug Files

### Visual Studio
- Install Visual Studio 2022 ([Installer](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&channel=Release&version=VS2022&source=VSLandingPage&cid=2030&passive=false))
- Desktop development with C++
Expand Down Expand Up @@ -141,9 +141,10 @@ Inside the INI file are `[sections]` and `key = value` pairs. The `[task]` secti
### `[task]`
Options for individual tasks. Can be `[task_name:task]`, where `task_name` is the name of a task (see `mob list`) , `super` for all MO tasks or a glob like `installer_*`.

| Option | Type | Description |
| --- | --- | --- |
| `enabled` | bool | Whether this task is enabled. Disabled tasks are never built. When specifying task names with `mob build task1 task2...`, all tasks except those given are turned off. |
| Option | Type | Description |
| --- | --- | --- |
| `enabled` | bool | Whether this task is enabled. Disabled tasks are never built. When specifying task names with `mob build task1 task2...`, all tasks except those given are turned off. |
| `configuration` | enum | Which configuration to build, should be one of Debug, Release or RelWithDebInfo with RelWithDebInfo being the default.|

#### Common git options
Unless otherwise stated, applies to any task that is a git repo.
Expand Down
118 changes: 85 additions & 33 deletions src/core/conf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ namespace mob::details {
using key_value_map = std::map<std::string, std::string, std::less<>>;
using section_map = std::map<std::string, key_value_map, std::less<>>;

static std::unordered_map<mob::config, std::string_view> s_configuration_values{
{mob::config::release, "Release"},
{mob::config::debug, "Debug"},
{mob::config::relwithdebinfo, "RelWithDebInfo"}};

// holds all the options not related to tasks (global, tools, paths, etc.)
static section_map g_conf;

Expand All @@ -27,6 +32,18 @@ namespace mob::details {
static int g_file_log_level = 5;
static bool g_dry = false;

// check if the two given string are equals case-insensitive
//
bool case_insensitive_equals(std::string_view lhs, std::string_view rhs)
{
// _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(lhs), std::end(lhs), std::begin(rhs),
std::end(rhs), [](auto&& c1, auto&& c2) {
return ::tolower(c1) == ::tolower(c2);
});
}

bool bool_from_string(std::string_view s)
{
return (s == "true" || s == "yes" || s == "1");
Expand Down Expand Up @@ -85,6 +102,17 @@ namespace mob::details {
kitor->second = value;
}

config string_to_config(std::string_view value)
{
for (const auto& [c, v] : s_configuration_values) {
if (case_insensitive_equals(value, v)) {
return c;
}
}

gcx().bail_out(context::conf, "invalid configuration '{}'", value);
}

// sets the given option, adds it if it doesn't exist; used when setting options
// from the master ini
//
Expand Down Expand Up @@ -184,6 +212,28 @@ namespace mob::details {
g_tasks[task_name][key] = std::move(value);
}

// read a CMake constant from the configuration
//
template <typename T>
T parse_cmake_value(std::string_view section, std::string_view key,
std::string_view value,
std::unordered_map<T, std::string_view> const& values)
{
for (const auto& [value_c, value_s] : values) {
if (case_insensitive_equals(value_s, value)) {
return value_c;
}
}

// build a string containing allowed value for logging
std::vector<std::string_view> values_s;
for (const auto& [value_c, value_s] : values) {
values_s.push_back(value_s);
}
gcx().bail_out(context::conf, "bad value '{}' for {}/{} (expected one of {})",
value, section, key, join(values_s, ", ", std::string{}));
}

} // namespace mob::details

namespace mob {
Expand Down Expand Up @@ -644,6 +694,11 @@ namespace mob {
return {};
}

conf_build_types conf::build_types()
{
return {};
}

conf_paths conf::path()
{
return {};
Expand All @@ -666,57 +721,52 @@ namespace mob {
return details::g_dry;
}

conf_task::conf_task(std::vector<std::string> names) : names_(std::move(names)) {}
// use appropriate case for the below constants since we will be using them in
// to_string, although most of cmake and msbuild is case-insensitive so it will
// not matter much in the end

std::string conf_task::get(std::string_view key) const
static std::unordered_map<conf_cmake::constant, std::string_view> constant_values{
{conf_cmake::always, "ALWAYS"},
{conf_cmake::lazy, "LAZY"},
{conf_cmake::never, "NEVER"}};

std::string conf_cmake::to_string(constant c)
{
return details::get_string_for_task(names_, key);
return std::string{constant_values.at(c)};
}

bool conf_task::get_bool(std::string_view key) const
conf_cmake::conf_cmake() : conf_section("cmake") {}

conf_cmake::constant conf_cmake::install_message() const
{
return details::get_bool_for_task(names_, key);
return details::parse_cmake_value(
name(), "install_message", details::get_string(name(), "install_message"),
constant_values);
}

bool conf_cmake::cmake_constant::is_equivalent(std::string_view other) const
std::string conf_cmake::host() 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);
});
return details::get_string(name(), "host");
}

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_task::conf_task(std::vector<std::string> names) : names_(std::move(names)) {}

conf_cmake::cmake_constant conf_cmake::install_message() const
std::string conf_task::get(std::string_view key) const
{
return read_cmake_constant("install_message", {ALWAYS, LAZY, NEVER});
return details::get_string_for_task(names_, key);
}

std::string conf_cmake::host() const
bool conf_task::get_bool(std::string_view key) const
{
return details::get_string(name(), "host");
return details::get_bool_for_task(names_, key);
}

conf_cmake::cmake_constant
conf_cmake::read_cmake_constant(std::string_view key,
std::vector<cmake_constant> const& allowed) const
mob::config conf_task::configuration() 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{}));
return details::parse_cmake_value(
names_[0], "configuration",
details::get_string_for_task(names_, "configuration"),
details::s_configuration_values);
}

conf_tools::conf_tools() : conf_section("tools") {}
Expand All @@ -725,6 +775,8 @@ namespace mob {

conf_versions::conf_versions() : conf_section("versions") {}

conf_build_types::conf_build_types() : conf_section("build-types") {}

conf_prebuilt::conf_prebuilt() : conf_section("prebuilt") {}

conf_paths::conf_paths() : conf_section("paths") {}
Expand Down
Loading

0 comments on commit ecd210d

Please sign in to comment.