mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
Add options to INI file to build some third-party dependencies in debug mode.
This commit is contained in:
@@ -120,6 +120,11 @@ libbsarch = 0.0.9
|
||||
usvfs = master
|
||||
explorerpp = 1.4.0
|
||||
|
||||
[build-types]
|
||||
libbsarch = release
|
||||
pyqt = release
|
||||
python = release
|
||||
|
||||
ss_paper_lad_6788 = 7.2
|
||||
ss_paper_automata_6788 = 3.2
|
||||
ss_paper_mono_6788 = 3.2
|
||||
|
||||
+36
-17
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
@@ -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
|
||||
//
|
||||
@@ -184,18 +212,6 @@ namespace mob::details {
|
||||
g_tasks[task_name][key] = std::move(value);
|
||||
}
|
||||
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
|
||||
// read a CMake constant from the configuration
|
||||
//
|
||||
template <typename T>
|
||||
@@ -678,6 +694,11 @@ namespace mob {
|
||||
return {};
|
||||
}
|
||||
|
||||
conf_build_types conf::build_types()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
conf_paths conf::path()
|
||||
{
|
||||
return {};
|
||||
@@ -742,14 +763,10 @@ namespace mob {
|
||||
|
||||
mob::config conf_task::configuration() const
|
||||
{
|
||||
static std::unordered_map<mob::config, std::string_view> configuration_values{
|
||||
{mob::config::release, "Release"},
|
||||
{mob::config::debug, "Debug"},
|
||||
{mob::config::relwithdebinfo, "RelWithDebInfo"}};
|
||||
return details::parse_cmake_value(
|
||||
names_[0], "configuration",
|
||||
details::get_string_for_task(names_, "configuration"),
|
||||
configuration_values);
|
||||
details::s_configuration_values);
|
||||
}
|
||||
|
||||
conf_tools::conf_tools() : conf_section("tools") {}
|
||||
@@ -758,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") {}
|
||||
|
||||
+29
-4
@@ -11,6 +11,18 @@ namespace mob::details {
|
||||
//
|
||||
std::string get_string(std::string_view section, std::string_view key);
|
||||
|
||||
// convert a string to the given type
|
||||
template <class T>
|
||||
T string_to(std::string_view value);
|
||||
|
||||
config string_to_config(std::string_view value);
|
||||
|
||||
template <>
|
||||
inline config string_to<config>(std::string_view value)
|
||||
{
|
||||
return string_to_config(value);
|
||||
}
|
||||
|
||||
// calls get_string(), converts to bool
|
||||
//
|
||||
bool get_bool(std::string_view section, std::string_view key);
|
||||
@@ -50,7 +62,14 @@ namespace mob {
|
||||
public:
|
||||
DefaultType get(std::string_view key) const
|
||||
{
|
||||
return details::get_string(name_, key);
|
||||
const auto value = details::get_string(name_, key);
|
||||
|
||||
if constexpr (std::is_convertible_v<std::string, DefaultType>) {
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
return details::string_to<DefaultType>(value);
|
||||
}
|
||||
}
|
||||
|
||||
// undefined
|
||||
@@ -197,6 +216,13 @@ namespace mob {
|
||||
conf_versions();
|
||||
};
|
||||
|
||||
// options in [build-types]
|
||||
//
|
||||
class conf_build_types : public conf_section<config> {
|
||||
public:
|
||||
conf_build_types();
|
||||
};
|
||||
|
||||
// options in [prebuilt]
|
||||
//
|
||||
class conf_prebuilt : public conf_section<std::string> {
|
||||
@@ -211,9 +237,7 @@ namespace mob {
|
||||
conf_paths();
|
||||
|
||||
#define VALUE(NAME) \
|
||||
fs::path NAME() const \
|
||||
{ \
|
||||
return get(#NAME); \
|
||||
fs::path NAME() const {return get(#NAME); \
|
||||
}
|
||||
|
||||
VALUE(third_party);
|
||||
@@ -261,6 +285,7 @@ namespace mob {
|
||||
conf_transifex transifex();
|
||||
conf_prebuilt prebuilt();
|
||||
conf_versions version();
|
||||
conf_build_types build_types();
|
||||
conf_paths path();
|
||||
|
||||
// opens the log file, creates the directory if needed
|
||||
|
||||
@@ -7,7 +7,9 @@ namespace mob::tasks {
|
||||
|
||||
std::string dir_name()
|
||||
{
|
||||
return "libbsarch-" + libbsarch::version() + "-release-x64";
|
||||
return "libbsarch-" + libbsarch::version() + "-" +
|
||||
(libbsarch::build_type() == config::debug ? "debug" : "release") +
|
||||
"-x64";
|
||||
}
|
||||
|
||||
url source_url()
|
||||
@@ -25,6 +27,11 @@ namespace mob::tasks {
|
||||
return conf().version().get("libbsarch");
|
||||
}
|
||||
|
||||
config libbsarch::build_type()
|
||||
{
|
||||
return conf().build_types().get("libbsarch");
|
||||
}
|
||||
|
||||
bool libbsarch::prebuilt()
|
||||
{
|
||||
return false;
|
||||
|
||||
+30
-22
@@ -86,6 +86,11 @@ namespace mob::tasks {
|
||||
return source_path() / "build";
|
||||
}
|
||||
|
||||
config pyqt::build_type()
|
||||
{
|
||||
return conf().build_types().get("pyqt");
|
||||
}
|
||||
|
||||
std::string pyqt::pyqt_sip_module_name()
|
||||
{
|
||||
return "PyQt6.sip";
|
||||
@@ -210,29 +215,28 @@ namespace mob::tasks {
|
||||
// here instead
|
||||
op::delete_directory(cx(), source_path() / "build", op::optional);
|
||||
|
||||
auto p = sip::sip_install_process()
|
||||
.arg("--confirm-license")
|
||||
.arg("--verbose", process::log_trace)
|
||||
.arg("--pep484-pyi")
|
||||
.arg("--link-full-dll")
|
||||
.arg("--build-dir", build_path())
|
||||
.cwd(source_path())
|
||||
.env(pyqt_env);
|
||||
|
||||
if (build_type() == config::debug) {
|
||||
p.arg("--debug");
|
||||
}
|
||||
|
||||
// build modules
|
||||
run_tool(process_runner(process()
|
||||
.binary(sip::sip_install_exe())
|
||||
.arg("--confirm-license")
|
||||
.arg("--verbose", process::log_trace)
|
||||
.arg("--pep484-pyi")
|
||||
.arg("--link-full-dll")
|
||||
.arg("--build-dir", build_path())
|
||||
// .arg("--enable",
|
||||
//"pylupdate") // these are not in modules so
|
||||
// they .arg("--enable", "pyrcc") // don't
|
||||
// get copied below
|
||||
// .args(zip(repeat("--enable"), modules()))
|
||||
.cwd(source_path())
|
||||
.env(pyqt_env)));
|
||||
run_tool(process_runner(p));
|
||||
|
||||
// done, create the bypass file
|
||||
built_bypass.create();
|
||||
}
|
||||
|
||||
// generate the PyQt6_sip-XX.tar.gz file
|
||||
run_tool(process_runner(process()
|
||||
.binary(sip::sip_module_exe())
|
||||
run_tool(process_runner(sip::sip_module_process()
|
||||
.arg("--sdist")
|
||||
.arg(pyqt_sip_module_name())
|
||||
.cwd(conf().path().cache())
|
||||
@@ -267,13 +271,17 @@ namespace mob::tasks {
|
||||
// python-XX/PCBuild/amd64, those are needed by PyQt6 when building several
|
||||
// projects
|
||||
|
||||
op::copy_file_to_dir_if_better(cx(), qt::bin_path() / "Qt6Core.dll",
|
||||
python::build_path(),
|
||||
op::unsafe); // source file is outside prefix
|
||||
const std::vector<std::string> dlls{"Qt6Core", "Qt6Xml"};
|
||||
|
||||
op::copy_file_to_dir_if_better(cx(), qt::bin_path() / "Qt6Xml.dll",
|
||||
python::build_path(),
|
||||
op::unsafe); // source file is outside prefix
|
||||
for (auto dll : dlls) {
|
||||
if (build_type() == config::debug) {
|
||||
dll += "d";
|
||||
}
|
||||
dll += ".dll";
|
||||
op::copy_file_to_dir_if_better(
|
||||
cx(), qt::bin_path() / dll, python::build_path(),
|
||||
op::unsafe); // source file is outside prefix
|
||||
}
|
||||
|
||||
// installation of PyQt6 python files (.pyd, etc.) is done
|
||||
// by the python plugin directly
|
||||
|
||||
+26
-11
@@ -89,6 +89,11 @@ namespace mob::tasks {
|
||||
return source_path() / "PCBuild" / "amd64";
|
||||
}
|
||||
|
||||
config python::build_type()
|
||||
{
|
||||
return conf().build_types().get("python");
|
||||
}
|
||||
|
||||
void python::do_clean(clean c)
|
||||
{
|
||||
if (prebuilt()) {
|
||||
@@ -190,16 +195,22 @@ namespace mob::tasks {
|
||||
|
||||
const auto bat = source_path() / "python.bat";
|
||||
|
||||
auto p = process()
|
||||
.binary(bat)
|
||||
.arg(fs::path("PC/layout"))
|
||||
.arg("--source", source_path())
|
||||
.arg("--build", build_path())
|
||||
.arg("--temp", (build_path() / "pythoncore_temp"))
|
||||
.arg("--copy", (build_path() / "pythoncore"))
|
||||
.arg("--preset-embed")
|
||||
.cwd(source_path());
|
||||
|
||||
if (build_type() == config::debug) {
|
||||
p = p.arg("--debug");
|
||||
}
|
||||
|
||||
// package libs into pythonXX.zip
|
||||
run_tool(process_runner(process()
|
||||
.binary(bat)
|
||||
.arg(fs::path("PC/layout"))
|
||||
.arg("--source", source_path())
|
||||
.arg("--build", build_path())
|
||||
.arg("--temp", (build_path() / "pythoncore_temp"))
|
||||
.arg("--copy", (build_path() / "pythoncore"))
|
||||
.arg("--preset-embed")
|
||||
.cwd(source_path())));
|
||||
run_tool(process_runner(p));
|
||||
}
|
||||
|
||||
void python::copy_files()
|
||||
@@ -210,7 +221,9 @@ namespace mob::tasks {
|
||||
|
||||
// pdbs
|
||||
op::copy_file_to_dir_if_better(
|
||||
cx(), build_path() / ("python" + version_for_dll() + ".pdb"),
|
||||
cx(),
|
||||
build_path() / ("python" + version_for_dll() +
|
||||
(build_type() == config::debug ? "_d" : "") + ".pdb"),
|
||||
conf().path().install_pdbs());
|
||||
|
||||
// dlls and python libraries are installed by the python plugin
|
||||
@@ -229,6 +242,7 @@ namespace mob::tasks {
|
||||
.solution(solution_file())
|
||||
.targets({"python", "pythonw", "python3dll", "select", "pyexpat",
|
||||
"unicodedata", "_queue", "_bz2", "_ssl", "_overlapped"})
|
||||
.configuration(build_type())
|
||||
.properties(
|
||||
{"bz2Dir=" + path_to_utf8(bzip2::source_path()),
|
||||
"zlibDir=" + path_to_utf8(zlib::source_path()),
|
||||
@@ -238,7 +252,8 @@ namespace mob::tasks {
|
||||
|
||||
fs::path python::python_exe()
|
||||
{
|
||||
return build_path() / "python.exe";
|
||||
return build_path() /
|
||||
(build_type() == config::debug ? "python_d.exe" : "python.exe");
|
||||
}
|
||||
|
||||
fs::path python::include_path()
|
||||
|
||||
+14
-7
@@ -62,14 +62,14 @@ namespace mob::tasks {
|
||||
return conf().path().build() / ("sip-" + version());
|
||||
}
|
||||
|
||||
fs::path sip::sip_module_exe()
|
||||
process sip::sip_module_process()
|
||||
{
|
||||
return python::scripts_path() / "sip-module.exe";
|
||||
return process().binary(python::scripts_path() / "sip-module.exe");
|
||||
}
|
||||
|
||||
fs::path sip::sip_install_exe()
|
||||
process sip::sip_install_process()
|
||||
{
|
||||
return python::scripts_path() / "sip-install.exe";
|
||||
return process().binary(python::scripts_path() / "sip-install.exe");
|
||||
}
|
||||
|
||||
fs::path sip::module_source_path()
|
||||
@@ -140,7 +140,15 @@ namespace mob::tasks {
|
||||
|
||||
void sip::build()
|
||||
{
|
||||
run_tool(pip(pip::install).file(source_path()));
|
||||
if (python::build_type() == config::debug) {
|
||||
// if Python is build in debug mode, fall back to old setup.py because pip
|
||||
// install seems to generated broken script wrapper that point to a
|
||||
// non-existing python.exe instead of python_d.exe
|
||||
run_tool(mob::python().root(source_path()).arg("setup.py").arg("install"));
|
||||
}
|
||||
else {
|
||||
run_tool(pip(pip::install).file(source_path()));
|
||||
}
|
||||
}
|
||||
|
||||
void sip::convert_script_file_to_acp(const std::string& filename)
|
||||
@@ -184,8 +192,7 @@ namespace mob::tasks {
|
||||
{
|
||||
// generate sip.h, will be copied to python's include directory, used
|
||||
// by plugin_python
|
||||
run_tool(process_runner(process()
|
||||
.binary(sip_module_exe())
|
||||
run_tool(process_runner(sip_module_process()
|
||||
.chcp(65001)
|
||||
.stdout_encoding(encodings::acp)
|
||||
.stderr_encoding(encodings::acp)
|
||||
|
||||
+8
-2
@@ -124,6 +124,7 @@ namespace mob::tasks {
|
||||
libbsarch();
|
||||
|
||||
static std::string version();
|
||||
static config build_type();
|
||||
static bool prebuilt();
|
||||
static fs::path source_path();
|
||||
|
||||
@@ -362,6 +363,7 @@ namespace mob::tasks {
|
||||
|
||||
static fs::path source_path();
|
||||
static fs::path build_path();
|
||||
static config build_type();
|
||||
|
||||
// "PyQt5.sip", used both in pyqt and sip
|
||||
//
|
||||
@@ -421,6 +423,10 @@ namespace mob::tasks {
|
||||
//
|
||||
static fs::path site_packages_path();
|
||||
|
||||
// configuration to build
|
||||
//
|
||||
static config build_type();
|
||||
|
||||
protected:
|
||||
void do_clean(clean c) override;
|
||||
void do_fetch() override;
|
||||
@@ -480,8 +486,8 @@ namespace mob::tasks {
|
||||
static bool prebuilt();
|
||||
|
||||
static fs::path source_path();
|
||||
static fs::path sip_module_exe();
|
||||
static fs::path sip_install_exe();
|
||||
static process sip_module_process();
|
||||
static process sip_install_process();
|
||||
static fs::path module_source_path();
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user