diff --git a/mob.ini b/mob.ini
index d79b962..ccf92a2 100644
--- a/mob.ini
+++ b/mob.ini
@@ -47,6 +47,7 @@ git_shallow = false
[usvfs:task]
git_shallow = false
+configuration = Release
[installer:task]
enabled = false
@@ -84,40 +85,14 @@ force = false
configure = true
pull = true
-[prebuilt]
-boost = true
-lz4 = true
-openssl = true
-pyqt = true
-python = true
-
[versions]
vs = 17
vs_year = 2022
vs_toolset = 14.3
sdk = 10.0.26100.0
-sevenz = 24.09
-boost = 1.88.0
-boost_vs = 14.3
-fmt = 11.1.4
-gtest = main
-directxtex = main
-libloot = 0.26.1
-lz4 = v1.10.0
-nmm = 0.71.2
-openssl = 3.5.0
pyqt = 6.7.1
-pyqt_builder = 1.16.4
-pyqt_sip = 13.8.0
-python = v3.12.10
-pybind11 = v2.12.1
-bzip2 = 1.0.8
-sip = 6.8.6
-spdlog = v1.15.2
qt = 6.7.3
qt_vs = 2022
-zlib = v1.3.1
-libbsarch = 0.0.12
usvfs = master
explorerpp = 1.4.0
ss_paper_lad_6788 = 7.2
@@ -130,16 +105,10 @@ 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 =
cache =
-patches =
licenses =
build =
install =
@@ -148,11 +117,9 @@ install_installer =
install_libs =
install_pdbs =
install_dlls =
-install_loot =
install_plugins =
install_stylesheets =
install_licenses =
-install_pythoncore =
install_translations =
vs =
vcpkg =
diff --git a/patches/pyqt/builder.py.manual_patch b/patches/pyqt/builder.py.manual_patch
deleted file mode 100644
index e2f536a..0000000
--- a/patches/pyqt/builder.py.manual_patch
+++ /dev/null
@@ -1,36 +0,0 @@
---- builder.py (date 1575938575861)
-+++ builder.py (date 1575938575861)
-@@ -402,17 +402,29 @@
- 'QMAKE_LFLAGS += -Wl,--version-script={}.exp'.format(
- buildable.target))
-
-- pro_lines.append(
-+ if project.py_platform == 'win32':
-+ for include_dir in project.py_include_dir.split(';'):
-+ pro_lines.append(
-+ 'INCLUDEPATH += {}'.format(
-+ self.qmake_quote(include_dir)))
-+ else:
-+ pro_lines.append(
- 'INCLUDEPATH += {}'.format(
-- self.qmake_quote(project.py_include_dir)))
-+ self.qmake_quote(project.py_include_dir)))
-
-+ if project.py_pylib_shlib != "":
-+ pro_lines.append(
-+ 'DEFINES += {}'.format(
-+ self.qmake_quote("PYTHON_LIB=\"{}\"".format(
-+ project.py_pylib_shlib))))
-+
- # Python.h on Windows seems to embed the need for pythonXY.lib, so tell
- # it where it is.
- # TODO: is this still necessary for Python v3.8?
- if not buildable.static:
- pro_lines.extend(['win32 {',
-- ' LIBS += -L{}'.format(
-- self.qmake_quote(project.py_pylib_dir)),
-+ ' LIBS += -L{}{}'.format(
-+ self.qmake_quote(project.py_pylib_dir), '' if project.py_pylib_lib == '' else ' -l' + project.py_pylib_lib),
- '}'])
-
- # Add any installables from the buildable
diff --git a/patches/python/sources/openssl.props.patch b/patches/python/sources/openssl.props.patch
deleted file mode 100644
index d60f6cb..0000000
--- a/patches/python/sources/openssl.props.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- PCbuild/openssl.props (revision 5c02a39a0b31a330e06b4d6f44835afb205dc7cc)
-+++ PCbuild/openssl.props (date 1575994670797)
-@@ -13,6 +13,7 @@
- <_DLLSuffix>-3
- <_DLLSuffix Condition="$(Platform) == 'ARM'">$(_DLLSuffix)-arm
- <_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64
-+ <_DLLSuffix Condition="$(Platform) == 'x64'">$(_DLLSuffix)-x64
- $(_DLLSuffix)
-
-
diff --git a/src/cmd/cmake.cpp b/src/cmd/cmake.cpp
deleted file mode 100644
index f6ef356..0000000
--- a/src/cmd/cmake.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "pch.h"
-#include "../tasks/tasks.h"
-#include "commands.h"
-
-namespace mob {
-
- cmake_command::cmake_command() : command(requires_options) {}
-
- command::meta_t cmake_command::meta() const
- {
- return {"cmake", "runs cmake in a directory"};
- }
-
- clipp::group cmake_command::do_group()
- {
- return clipp::group(
- clipp::command("cmake").set(picked_),
-
- (clipp::option("-h", "--help") >> help_) % "shows this message",
-
- (clipp::option("-G", "--generator") & clipp::value("GEN") >> gen_) %
- ("sets the -G option for cmake [default: VS]"),
-
- (clipp::option("-c", "--cmd") & clipp::value("CMD") >> cmd_) %
- "overrides the cmake command line [default: \"..\"]",
-
- (clipp::option("--x64").set(x64_, true) |
- clipp::option("--x86").set(x64_, false)) %
- "whether to use the x64 or x86 vcvars; if -G is not set, "
- "whether to pass \"-A Win32\" or \"-A x64\" for the default "
- "VS generator [default: x64]",
-
- (clipp::option("--install-prefix") & clipp::value("PATH") >> prefix_) %
- "sets CMAKE_INSTALL_PREFIX [default: empty]",
-
- (clipp::option("-d", "--debug").set(debug_, true)) %
- "whether to configure for debug mode [default: false]",
-
- (clipp::value("PATH") >> path_) % "path from which to run `cmake`");
- }
-
- int cmake_command::do_run()
- {
- auto t = tasks::modorganizer::create_cmake_tool(
- fs::path(utf8_to_utf16(path_)), mob::cmake::generate,
- debug_ ? config::debug : config::relwithdebinfo);
-
- t.generator(gen_);
- t.cmd(cmd_);
- t.prefix(prefix_);
- t.output(path_);
-
- if (!x64_)
- t.architecture(arch::x86);
-
- // copy the global context, the tool will modify it
- context cxcopy(gcx());
-
- t.run(cxcopy);
-
- return 0;
- }
-
- std::string cmake_command::do_doc()
- {
- return "Runs `cmake ..` in the given directory with the same command line\n"
- "as the one used for modorganizer projects.";
- }
-
-} // namespace mob
diff --git a/src/cmd/cmake_config.cpp b/src/cmd/cmake_config.cpp
new file mode 100644
index 0000000..ccd7589
--- /dev/null
+++ b/src/cmd/cmake_config.cpp
@@ -0,0 +1,43 @@
+#include "pch.h"
+
+#include "../core/conf.h"
+#include "../tasks/tasks.h"
+
+#include "commands.h"
+
+namespace mob {
+
+ cmake_config_command::cmake_config_command() : command(requires_options) {}
+
+ command::meta_t cmake_config_command::meta() const
+ {
+ return {"cmake-config", "print CMake configuration variables"};
+ }
+
+ clipp::group cmake_config_command::do_group()
+ {
+ return clipp::group(
+ clipp::command("cmake-config").set(picked_),
+ (clipp::option("-h", "--help") >> help_) % ("shows this message"),
+ clipp::command("prefix-path").set(var_, variable::prefix_path) |
+ clipp::command("install-prefix").set(var_, variable::install_prefix));
+ }
+
+ std::string cmake_config_command::do_doc()
+ {
+ return "Print CMake variables to be used when configuring projects.\n";
+ }
+
+ int cmake_config_command::do_run()
+ {
+ switch (var_) {
+ case variable::prefix_path:
+ u8cout << tasks::modorganizer::cmake_prefix_path();
+ break;
+ case variable::install_prefix:
+ u8cout << conf().path().install().string();
+ break;
+ }
+ return 0;
+ }
+} // namespace mob
diff --git a/src/cmd/commands.h b/src/cmd/commands.h
index 267a133..801dec0 100644
--- a/src/cmd/commands.h
+++ b/src/cmd/commands.h
@@ -281,7 +281,6 @@ namespace mob {
void make_bin();
void make_pdbs();
void make_src();
- void make_uibase();
void make_installer();
protected:
@@ -297,7 +296,6 @@ namespace mob {
bool bin_ = true;
bool src_ = true;
bool pdbs_ = true;
- bool uibase_ = true;
bool installer_ = false;
std::string utf8out_;
fs::path out_;
@@ -367,27 +365,6 @@ namespace mob {
std::vector get_repos() const;
};
- // runs cmake in a directory with the same parameters as `build` would
- //
- class cmake_command : public command {
- public:
- cmake_command();
- meta_t meta() const override;
-
- protected:
- clipp::group do_group() override;
- int do_run() override;
- std::string do_doc() override;
-
- private:
- std::string gen_;
- std::string cmd_;
- bool x64_ = true;
- bool debug_ = false;
- std::string prefix_;
- std::string path_;
- };
-
// lists the inis found by mob
//
class inis_command : public command {
@@ -427,4 +404,20 @@ namespace mob {
void do_build();
};
+ // print CMake configuration variables
+ //
+ class cmake_config_command : public command {
+ public:
+ cmake_config_command();
+ meta_t meta() const override;
+
+ protected:
+ clipp::group do_group() override;
+ int do_run() override;
+ std::string do_doc() override;
+
+ enum class variable { prefix_path, install_prefix };
+ variable var_;
+ };
+
} // namespace mob
diff --git a/src/cmd/release.cpp b/src/cmd/release.cpp
index 31691b4..8ae786f 100644
--- a/src/cmd/release.cpp
+++ b/src/cmd/release.cpp
@@ -44,9 +44,19 @@ namespace mob {
u8cout << "making src archive " << path_to_utf8(out) << "\n";
const std::vector ignore = {"\\..+", // dot files
- ".*\\.log", ".*\\.tlog", ".*\\.dll",
- ".*\\.exe", ".*\\.lib", ".*\\.obj",
- ".*\\.ts", ".*\\.aps", "vsbuild"};
+ "explorer\\+\\+",
+ "stylesheets",
+ "transifex-translations"
+ ".*\\.log",
+ ".*\\.tlog",
+ ".*\\.dll",
+ ".*\\.exe",
+ ".*\\.lib",
+ ".*\\.obj",
+ ".*\\.ts",
+ ".*\\.aps",
+ "(bin|lib)",
+ "vsbuild(32|64)?"};
const std::vector ignore_re(ignore.begin(), ignore.end());
@@ -77,25 +87,6 @@ namespace mob {
op::archive_from_files(gcx(), files, tasks::modorganizer::super_path(), out);
}
- void release_command::make_uibase()
- {
- const auto out = out_ / make_filename("uibase");
- u8cout << "making uibase archive " << path_to_utf8(out) << "\n";
-
- std::vector files;
-
- if (!fs::exists(tasks::modorganizer::super_path())) {
- gcx().bail_out(context::generic, "modorganizer super path not found: {}",
- tasks::modorganizer::super_path());
- }
-
- op::archive_from_glob(
- gcx(), tasks::modorganizer::super_path() / "uibase" / "src" / "*.h", out,
- {});
- op::archive_from_files(gcx(), {conf().path().install_libs() / "uibase.lib"},
- conf().path().install_libs(), out);
- }
-
void release_command::make_installer()
{
const auto file = "Mod.Organizer-" + version_ + ".exe";
@@ -178,11 +169,6 @@ namespace mob {
clipp::option("--no-src").set(src_, false)) %
"sets whether the source archive is created [default: yes]",
- //(
- // clipp::option("--uibase").set(uibase_, true) |
- // clipp::option("--no-uibase").set(uibase_, false)
- //) % "sets whether the uibase archive is created [default: yes]",
-
(clipp::option("--inst").set(installer_, true) |
clipp::option("--no-inst").set(installer_, false)) %
"sets whether the installer is copied [default: no]",
@@ -271,9 +257,6 @@ namespace mob {
if (src_)
make_src();
- if (uibase_)
- make_uibase();
-
if (installer_)
make_installer();
@@ -299,7 +282,6 @@ namespace mob {
make_bin();
make_pdbs();
make_src();
- make_uibase();
make_installer();
return 0;
diff --git a/src/core/conf.cpp b/src/core/conf.cpp
index 82b38f1..b4b8583 100644
--- a/src/core/conf.cpp
+++ b/src/core/conf.cpp
@@ -512,7 +512,6 @@ namespace mob {
set_path_if_empty("vcpkg", find_vcpkg); // set after vs as it will use the VS
set_path_if_empty("qt_install", find_qt);
set_path_if_empty("temp_dir", find_temp_dir);
- set_path_if_empty("patches", find_in_root("patches"));
set_path_if_empty("licenses", find_in_root("licenses"));
set_path_if_empty("qt_bin", qt::installation_path() / "bin");
set_path_if_empty("qt_translations", qt::installation_path() / "translations");
@@ -534,10 +533,8 @@ namespace mob {
resolve_path("install_libs", p.install(), "lib");
resolve_path("install_pdbs", p.install(), "pdb");
resolve_path("install_dlls", p.install_bin(), "dlls");
- resolve_path("install_loot", p.install_bin(), "loot");
resolve_path("install_plugins", p.install_bin(), "plugins");
resolve_path("install_licenses", p.install_bin(), "licenses");
- resolve_path("install_pythoncore", p.install_bin(), "pythoncore");
resolve_path("install_stylesheets", p.install_bin(), "stylesheets");
resolve_path("install_translations", p.install_bin(), "translations");
@@ -685,11 +682,6 @@ namespace mob {
return {};
}
- conf_prebuilt conf::prebuilt()
- {
- return {};
- }
-
conf_versions conf::version()
{
return {};
diff --git a/src/core/conf.h b/src/core/conf.h
index c1cbcbe..4e147a3 100644
--- a/src/core/conf.h
+++ b/src/core/conf.h
@@ -245,7 +245,6 @@ namespace mob {
VALUE(third_party);
VALUE(prefix);
VALUE(cache);
- VALUE(patches);
VALUE(licenses);
VALUE(build);
@@ -256,11 +255,9 @@ namespace mob {
VALUE(install_pdbs);
VALUE(install_dlls);
- VALUE(install_loot);
VALUE(install_plugins);
VALUE(install_stylesheets);
VALUE(install_licenses);
- VALUE(install_pythoncore);
VALUE(install_translations);
VALUE(vs);
diff --git a/src/main.cpp b/src/main.cpp
index c912402..7119c6e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -24,36 +24,6 @@ namespace mob {
// mob doesn't have a concept of task dependencies, just task ordering, so
// if a task depends on another, it has to be earlier in the order
- // third-party tasks
-
- add_task()
- .add_task()
- .add_task()
- .add_task()
- .add_task()
- .add_task()
- .add_task()
- .add_task()
- .add_task();
-
- add_task()
- .add_task()
- .add_task()
- .add_task();
-
- add_task()
- .add_task()
- .add_task()
- .add_task();
-
- add_task()
- .add_task()
- .add_task()
- .add_task()
- .add_task()
- .add_task()
- .add_task();
-
// super tasks
using mo = modorganizer;
@@ -61,9 +31,9 @@ namespace mob {
// most of the alternate names below are from the transifex slugs, which
// are sometimes different from the project names, for whatever reason
- add_task()
- .add_task("cmake_common")
- .add_task("modorganizer-uibase");
+ add_task().add_task().add_task("cmake_common");
+
+ add_task("modorganizer-uibase");
add_task()
.add_task("modorganizer-archive")
@@ -72,35 +42,13 @@ namespace mob {
.add_task("modorganizer-bsatk")
.add_task("modorganizer-nxmhandler")
.add_task("modorganizer-helper")
- .add_task("githubpp")
- .add_task("modorganizer-game_gamebryo")
+ .add_task("modorganizer-game_bethesda");
+
+ add_task()
.add_task({"modorganizer-bsapacker", "bsa_packer"})
- .add_task("modorganizer-preview_bsa");
-
- // the gamebryo flag must be set for all game plugins that inherit from
- // the gamebryo classes; this will merge the .ts file from gamebryo with
- // the one from the specific plugin
- add_task()
- .add_task("modorganizer-game_oblivion", mo::gamebryo)
- .add_task("modorganizer-game_nehrim", mo::gamebryo)
- .add_task("modorganizer-game_fallout3", mo::gamebryo)
- .add_task("modorganizer-game_fallout4", mo::gamebryo)
- .add_task("modorganizer-game_fallout4vr", mo::gamebryo)
- .add_task("modorganizer-game_fallout76", mo::gamebryo)
- .add_task("modorganizer-game_fallout4london", mo::gamebryo)
- .add_task("modorganizer-game_falloutnv", mo::gamebryo)
- .add_task("modorganizer-game_morrowind", mo::gamebryo)
- .add_task("modorganizer-game_skyrim", mo::gamebryo)
- .add_task("modorganizer-game_skyrimse", mo::gamebryo)
- .add_task("modorganizer-game_skyrimvr", mo::gamebryo)
- .add_task("modorganizer-game_starfield", mo::gamebryo)
- .add_task("modorganizer-game_ttw", mo::gamebryo)
- .add_task("modorganizer-game_enderal", mo::gamebryo)
- .add_task("modorganizer-game_enderalse", mo::gamebryo);
-
- add_task()
.add_task({"modorganizer-tool_inieditor", "inieditor"})
.add_task({"modorganizer-tool_inibakery", "inibakery"})
+ .add_task("modorganizer-preview_bsa")
.add_task("modorganizer-preview_base")
.add_task("modorganizer-diagnose_basic")
.add_task("modorganizer-check_fnis")
@@ -110,12 +58,15 @@ namespace mob {
.add_task("modorganizer-installer_quick")
.add_task("modorganizer-installer_fomod")
.add_task("modorganizer-installer_fomod_csharp")
- .add_task("modorganizer-installer_omod", mo::nuget)
+ .add_task("modorganizer-installer_omod")
.add_task("modorganizer-installer_wizard")
.add_task("modorganizer-bsa_extractor")
.add_task("modorganizer-plugin_python");
add_task()
+ .add_task()
+ .add_task()
+ .add_task()
.add_task({"modorganizer-tool_configurator", "pycfg"})
.add_task("modorganizer-fnistool")
.add_task("modorganizer-basic_games")
@@ -126,7 +77,6 @@ namespace mob {
.add_task({"modorganizer", "organizer"});
// other tasks
-
add_task();
add_task();
}
@@ -148,9 +98,9 @@ namespace mob {
std::make_unique(),
std::make_unique(),
std::make_unique(),
- std::make_unique(),
std::make_unique(),
- std::make_unique()};
+ std::make_unique(),
+ std::make_unique()};
// commands are shown in the help
help->set_commands(commands);
diff --git a/src/tasks/boost.cpp b/src/tasks/boost.cpp
deleted file mode 100644
index 3289d22..0000000
--- a/src/tasks/boost.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-#include "pch.h"
-#include "../core/process.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- namespace {
- std::string boost_version_no_tags()
- {
- const auto v = boost::parsed_version();
-
- // 1.72[.1]
- std::string s = v.major + "." + v.minor;
-
- if (v.patch != "")
- s += "." + v.patch;
-
- return s;
- }
-
- std::string boost_version_dash()
- {
- const auto v = boost::parsed_version();
-
- // boost_1_72[_0[_b1_rc1]]
- std::string s = "Boost-" + v.major + "." + v.minor;
-
- if (v.patch != "")
- s += "." + v.patch;
-
- return s;
- }
-
- std::string boost_version_no_tags_underscores()
- {
- return replace_all(boost_version_no_tags(), ".", "_");
- }
-
- std::string boost_version_all_underscores()
- {
- const auto v = boost::parsed_version();
-
- // boost_1_72[_0[_b1_rc1]]
- std::string s = "boost_" + v.major + "_" + v.minor;
-
- if (v.patch != "")
- s += "_" + v.patch;
-
- if (v.rest != "")
- s += "_" + replace_all(v.rest, "-", "_");
-
- return s;
- }
-
- std::string address_model_for_arch(arch a)
- {
- switch (a) {
- case arch::x86:
- return "32";
-
- case arch::x64:
- case arch::dont_care:
- return "64";
-
- default:
- gcx().bail_out(context::generic, "boost: bad arch");
- }
- }
-
- fs::path config_jam_file()
- {
- return boost::source_path() / "user-config-64.jam";
- }
-
- url prebuilt_url()
- {
- const auto underscores = replace_all(boost::version(), ".", "_");
- return make_prebuilt_url("boost_prebuilt_" + underscores + ".7z");
- }
-
- url source_url()
- {
- return "https://archives.boost.io/release/" + boost_version_no_tags() +
- "/source/" + boost_version_all_underscores() + ".7z";
- }
-
- fs::path b2_exe()
- {
- return boost::source_path() / "b2.exe";
- }
-
- } // namespace
-
- boost::boost() : basic_task("boost") {}
-
- std::string boost::version()
- {
- return conf().version().get("boost");
- }
-
- std::string boost::version_vs()
- {
- return conf().version().get("boost_vs");
- }
-
- bool boost::prebuilt()
- {
- return conf().prebuilt().get("boost");
- }
-
- fs::path boost::source_path()
- {
- // ex: build/boost_1_74_0
- return conf().path().build() / ("boost_" + boost_version_no_tags_underscores());
- }
-
- fs::path boost::cmake_path(arch a)
- {
- return lib_path(a) / "cmake" / boost_version_dash();
- }
-
- fs::path boost::lib_path(arch a)
- {
- // ex: build/boost_1_74_0/lib64-msvc-14.2/lib
- return root_lib_path(a) / "lib";
- }
-
- fs::path boost::root_lib_path(arch a)
- {
- // ex: build/boost_1_74_0/lib64-msvc-14.2
-
- const std::string lib =
- "lib" + address_model_for_arch(a) + "-msvc-" + version_vs();
-
- return source_path() / lib;
- }
-
- void boost::do_clean(clean c)
- {
- if (is_set(c, clean::redownload)) {
- // delete downloaded file
-
- if (prebuilt())
- run_tool(downloader(prebuilt_url(), downloader::clean));
- else
- run_tool(downloader(source_url(), downloader::clean));
- }
-
- if (is_set(c, clean::reextract)) {
- // delete the whole thing
- cx().trace(context::reextract, "deleting {}", source_path());
- op::delete_directory(cx(), source_path(), op::optional);
-
- // no need for the rest
- return;
- }
-
- // those don't make sense for prebults
- if (!prebuilt()) {
- if (is_set(c, clean::reconfigure)) {
- // delete bin and b2.exe to make sure bootstrap runs again
- op::delete_directory(cx(), source_path() / "bin.v2", op::optional);
- op::delete_file(cx(), b2_exe(), op::optional);
-
- // delete jam files
- op::delete_file(cx(), config_jam_file(), op::optional);
- op::delete_file(cx(), source_path() / "project-config.jam",
- op::optional);
- }
-
- if (is_set(c, clean::rebuild)) {
- // delete libs
- op::delete_directory(cx(), root_lib_path(arch::x86), op::optional);
- op::delete_directory(cx(), root_lib_path(arch::x64), op::optional);
- }
- }
- }
-
- void boost::do_fetch()
- {
- if (prebuilt())
- fetch_prebuilt();
- else
- fetch_from_source();
- }
-
- void boost::do_build_and_install()
- {
- if (prebuilt())
- build_and_install_prebuilt();
- else
- build_and_install_from_source();
- }
-
- void boost::fetch_prebuilt()
- {
- cx().trace(context::generic, "using prebuilt boost");
-
- const auto file = run_tool(downloader(prebuilt_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void boost::build_and_install_prebuilt() {}
-
- void boost::fetch_from_source()
- {
- const auto file = run_tool(downloader(source_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void boost::bootstrap()
- {
- // bootstrap b2
-
- write_config_jam();
-
- const auto bootstrap = source_path() / "bootstrap.bat";
-
- run_tool(process_runner(process()
- .binary(bootstrap)
- .external_error_log(source_path() / "bootstrap.log")
- .cwd(source_path())));
- }
-
- void boost::build_and_install_from_source()
- {
- // bypass boostrap
- if (fs::exists(b2_exe())) {
- cx().trace(context::bypass, "{} exists, boost already bootstrapped",
- b2_exe());
- }
- else {
- bootstrap();
- }
-
- // we do not need all variants of all components but since people should
- // usually be using the pre-built, we can build everything without losing too
- // much time and it is much easier to deal when mixing
- //
- // note: filesystem is only required by USVFS I think, so maybe think about
- // removing it if we switch to std::filesystem in USVFS
- //
- clipp::arg_list components{"thread", "date_time", "filesystem", "locale",
- "program_options"};
-
- // static link, static runtime, x64
- do_b2(components, "static", "static", arch::x64);
-
- // static link, static/shared runtime, x86, required by usvfs 32-bit
- do_b2(components, "static", "static", arch::x86);
- do_b2(components, "static", "shared", arch::x86);
-
- // static link, shared runtime, x64
- do_b2(components, "static", "shared", arch::x64);
-
- // shared link, shared runtime, x64
- do_b2(components, "shared", "shared", arch::x64);
- }
-
- void boost::do_b2(const std::vector& components,
- const std::string& link, const std::string& runtime_link, arch a)
- {
- // will transform all components to --with-X
-
- run_tool(process_runner(process()
- .binary(b2_exe())
- .arg("address-model=", address_model_for_arch(a))
- .arg("link=", link)
- .arg("runtime-link=", runtime_link)
- .arg("toolset=", "msvc-" + vs::toolset())
- .arg("--user-config=", config_jam_file())
- .arg("--stagedir=", root_lib_path(a))
- .arg("--libdir=", root_lib_path(a))
- .args(map(components,
- [](auto&& c) {
- return "--with-" + c;
- }))
- .env(env::vs(a))
- .cwd(source_path())));
- }
-
- void boost::write_config_jam()
- {
- // b2 requires forward slashes
- auto forward_slashes = [](auto&& p) {
- std::string s = path_to_utf8(p);
- return replace_all(s, "\\", "/");
- };
-
- // this currently writes an empty configuration file, at some point it was used
- // to configure the Boost.Python built
- //
- // kept here in case we need a custom user-configuration in the future
- //
- std::ostringstream oss;
-
- // logging
- {
- cx().trace(context::generic,
- "writing config file at {}:", config_jam_file());
-
- for_each_line(oss.str(), [&](auto&& line) {
- cx().trace(context::generic, " {}", line);
- });
- }
-
- // writing
- op::write_text_file(cx(), encodings::utf8, config_jam_file(), oss.str());
- }
-
- boost::version_info boost::parsed_version()
- {
- // 1.72.0-b1-rc1
- // everything but 1.72 is optional
- std::regex re("(\\d+)\\." // 1.
- "(\\d+)" // 72
- "(?:"
- "\\.(\\d+)" // .0
- "(?:" //
- "-(.+)" // -b1-rc1
- ")?"
- ")?");
-
- std::smatch m;
-
- const auto s = version();
-
- if (!std::regex_match(s, m, re))
- gcx().bail_out(context::generic, "bad boost version '{}'", s);
-
- return {m[1], m[2], m[3], m[4]};
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/boost_di.cpp b/src/tasks/boost_di.cpp
deleted file mode 100644
index fddbaad..0000000
--- a/src/tasks/boost_di.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "pch.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- // boost-di is needed by bsapacker
-
- boost_di::boost_di() : basic_task("boost-di", "boostdi", "boost_di") {}
-
- std::string boost_di::version()
- {
- return {};
- }
-
- bool boost_di::prebuilt()
- {
- // prebuilts don't exist for this, it's headers only
- return false;
- }
-
- fs::path boost_di::source_path()
- {
- return conf().path().build() / "di";
- }
-
- void boost_di::do_clean(clean c)
- {
- // delete the whole thing
- if (is_set(c, clean::reclone))
- git_wrap::delete_directory(cx(), source_path());
- }
-
- void boost_di::do_fetch()
- {
- run_tool(make_git()
- .url(make_git_url("boost-experimental", "di"))
- .branch("cpp14")
- .root(source_path()));
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/bzip2.cpp b/src/tasks/bzip2.cpp
deleted file mode 100644
index 253ed4c..0000000
--- a/src/tasks/bzip2.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#include "pch.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- // required by python
-
- namespace {
-
- url source_url()
- {
- return "https://sourceware.org/pub/bzip2/"
- "bzip2-" +
- bzip2::version() + ".tar.gz";
- }
-
- } // namespace
-
- bzip2::bzip2() : basic_task("bzip2") {}
-
- std::string bzip2::version()
- {
- return conf().version().get("bzip2");
- }
-
- bool bzip2::prebuilt()
- {
- // no prebuilts, just the source, required by python, which uses the
- // source files directly
- return false;
- }
-
- fs::path bzip2::source_path()
- {
- return conf().path().build() / ("bzip2-" + version());
- }
-
- void bzip2::do_clean(clean c)
- {
- // delete download
- if (is_set(c, clean::redownload))
- run_tool(downloader(source_url(), downloader::clean));
-
- // delete the whole directory
- if (is_set(c, clean::reextract)) {
- cx().trace(context::reextract, "deleting {}", source_path());
- op::delete_directory(cx(), source_path(), op::optional);
- }
- }
-
- void bzip2::do_fetch()
- {
- const auto file = run_tool(downloader(source_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/directxtex.cpp b/src/tasks/directxtex.cpp
deleted file mode 100644
index b7d79f2..0000000
--- a/src/tasks/directxtex.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "pch.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- namespace {
-
- msbuild create_msbuild_tool(arch a, config config,
- msbuild::ops o = msbuild::build)
- {
- return std::move(msbuild(o).architecture(a).configuration(config).solution(
- directxtex::source_path() / "DirectXTex" /
- "DirectXTex_Desktop_2022.vcxproj"));
- }
-
- } // namespace
-
- directxtex::directxtex() : basic_task("directxtex") {}
-
- std::string directxtex::version()
- {
- return conf().version().get("directxtex");
- }
-
- bool directxtex::prebuilt()
- {
- return false;
- }
-
- fs::path directxtex::source_path()
- {
- return conf().path().build() / "DirectXTex";
- }
-
- void directxtex::do_clean(clean c)
- {
- if (is_set(c, clean::reclone)) {
- git_wrap::delete_directory(cx(), source_path());
- return;
- }
-
- if (is_set(c, clean::rebuild)) {
- run_tool(create_msbuild_tool(arch::x64, config::release, msbuild::clean));
- run_tool(create_msbuild_tool(arch::x64, config::debug, msbuild::clean));
- }
- }
-
- void directxtex::do_fetch()
- {
- run_tool(make_git()
- .url(make_git_url("microsoft", "DirectXTex"))
- .branch(version())
- .root(source_path()));
- }
-
- void directxtex::do_build_and_install()
- {
- op::create_directories(cx(), directxtex::source_path() / "Include");
- op::create_directories(cx(), directxtex::source_path() / "Lib" / "Debug");
- op::create_directories(cx(), directxtex::source_path() / "Lib" / "Release");
-
- // DO NOT run these in parallel because both generate files that are shared
- // between release and debug
- run_tool(create_msbuild_tool(arch::x64, config::release));
- run_tool(create_msbuild_tool(arch::x64, config::debug));
-
- const auto binary_path =
- source_path() / "DirectXTex" / "Bin" / "Desktop_2022" / "x64";
-
- for (const auto& header : {"DDS.h", "DirectXTex.h", "DirectXTex.inl "}) {
- op::copy_file_to_dir_if_better(cx(), source_path() / "DirectXTex" / header,
- source_path() / "Include");
- }
- op::copy_file_to_dir_if_better(cx(), binary_path / "Debug" / "DirectXTex.lib",
- source_path() / "Lib" / "Debug");
- op::copy_file_to_dir_if_better(cx(), binary_path / "Release" / "DirectXTex.lib",
- source_path() / "Lib" / "Release");
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/gtest.cpp b/src/tasks/gtest.cpp
deleted file mode 100644
index 359a433..0000000
--- a/src/tasks/gtest.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "pch.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- namespace {
-
- cmake create_cmake_tool(arch a, config config, cmake::ops o = cmake::generate)
- {
- return std::move(cmake(o)
- .generator(cmake::vs)
- .architecture(a)
- .arg("-Wno-deprecated")
- .arg("-Dgtest_force_shared_crt=ON")
- .prefix(gtest::build_path(a, config))
- .root(gtest::source_path()));
- }
-
- msbuild create_msbuild_tool(arch a, config config,
- msbuild::ops o = msbuild::build)
- {
- const fs::path build_path = create_cmake_tool(a, config).build_path();
-
- return std::move(msbuild(o).architecture(a).configuration(config).solution(
- build_path / "INSTALL.vcxproj"));
- }
-
- } // namespace
-
- gtest::gtest() : basic_task("gtest", "googletest") {}
-
- std::string gtest::version()
- {
- return conf().version().get("gtest");
- }
-
- bool gtest::prebuilt()
- {
- return false;
- }
-
- fs::path gtest::source_path()
- {
- return conf().path().build() / "googletest";
- }
-
- fs::path gtest::build_path(arch a, config c)
- {
- return source_path() / "build" / (a == arch::x64 ? "x64" : "Win32") /
- msbuild::configuration_name(c);
- }
-
- void gtest::do_clean(clean c)
- {
- if (is_set(c, clean::reclone)) {
- git_wrap::delete_directory(cx(), source_path());
- return;
- }
-
- if (is_set(c, clean::reconfigure)) {
- run_tool(create_cmake_tool(arch::x86, config::release, cmake::clean));
- run_tool(create_cmake_tool(arch::x64, config::release, cmake::clean));
- }
-
- if (is_set(c, clean::rebuild)) {
- run_tool(create_msbuild_tool(arch::x86, config::release, msbuild::clean));
- run_tool(create_msbuild_tool(arch::x86, config::debug, msbuild::clean));
- run_tool(create_msbuild_tool(arch::x64, config::release, msbuild::clean));
- run_tool(create_msbuild_tool(arch::x64, config::debug, msbuild::clean));
- }
- }
-
- void gtest::do_fetch()
- {
- run_tool(make_git()
- .url(make_git_url("google", "googletest"))
- .branch(version())
- .root(source_path()));
- }
-
- void gtest::do_build_and_install()
- {
- op::create_directories(cx(), gtest::build_path(arch::x64).parent_path());
- op::create_directories(cx(), gtest::build_path(arch::x86).parent_path());
-
- parallel({{"gtest64",
- [&] {
- run_tool(create_cmake_tool(arch::x64, config::release));
- run_tool(create_msbuild_tool(arch::x64, config::release));
-
- run_tool(create_cmake_tool(arch::x64, config::debug));
- run_tool(create_msbuild_tool(arch::x64, config::debug));
- }},
-
- {"gtest32", [&] {
- run_tool(create_cmake_tool(arch::x86, config::release));
- run_tool(create_msbuild_tool(arch::x86, config::release));
-
- run_tool(create_cmake_tool(arch::x86, config::debug));
- run_tool(create_msbuild_tool(arch::x86, config::debug));
- }}});
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/installer.cpp b/src/tasks/installer.cpp
index f90db80..8feb3c6 100644
--- a/src/tasks/installer.cpp
+++ b/src/tasks/installer.cpp
@@ -36,9 +36,21 @@ namespace mob::tasks {
{
const std::string repo = "modorganizer-Installer";
+ // find the best suitable branch
+ const auto fallback = task_conf().mo_fallback_branch();
+ auto branch = task_conf().mo_branch();
+ if (!fallback.empty() &&
+ !git_wrap::remote_branch_exists(make_git_url(task_conf().mo_org(), repo),
+ branch)) {
+ cx().warning(context::generic,
+ "{} has no remote {} branch, switching to {}", repo, branch,
+ fallback);
+ branch = fallback;
+ }
+
run_tool(make_git()
.url(make_git_url(task_conf().mo_org(), repo))
- .branch(task_conf().mo_branch())
+ .branch(branch)
.root(source_path()));
}
diff --git a/src/tasks/libbsarch.cpp b/src/tasks/libbsarch.cpp
deleted file mode 100644
index de41c56..0000000
--- a/src/tasks/libbsarch.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "pch.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- namespace {
-
- std::string dir_name()
- {
- return "libbsarch-" + libbsarch::version() + "-" +
- (libbsarch::build_type() == config::debug ? "debug" : "release") +
- "-x64";
- }
-
- url source_url()
- {
- return "https://github.com/ModOrganizer2/libbsarch/releases/download/" +
- libbsarch::version() + "/" + dir_name() + ".7z";
- }
-
- } // namespace
-
- libbsarch::libbsarch() : basic_task("libbsarch") {}
-
- std::string libbsarch::version()
- {
- return conf().version().get("libbsarch");
- }
-
- config libbsarch::build_type()
- {
- return conf().build_types().get("libbsarch");
- }
-
- bool libbsarch::prebuilt()
- {
- return false;
- }
-
- fs::path libbsarch::source_path()
- {
- return conf().path().build() / dir_name();
- }
-
- void libbsarch::do_clean(clean c)
- {
- // delete the download
- if (is_set(c, clean::redownload))
- run_tool(downloader(source_url(), downloader::clean));
-
- // delete the whole directory
- if (is_set(c, clean::reextract)) {
- cx().trace(context::reextract, "deleting {}", source_path());
- op::delete_directory(cx(), source_path(), op::optional);
- }
- }
-
- void libbsarch::do_fetch()
- {
- const auto file = run_tool(downloader(source_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void libbsarch::do_build_and_install()
- {
- // copy dll
- op::copy_file_to_dir_if_better(cx(), source_path() / "libbsarch.dll",
- conf().path().install_dlls());
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/libloot.cpp b/src/tasks/libloot.cpp
deleted file mode 100644
index 0715848..0000000
--- a/src/tasks/libloot.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#include "pch.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- namespace {
-
- std::string release_name()
- {
- // the naming convention is `libloot-version-win64.7z`,
- // such as libloot-0.19.3-win64.7z.
- return "libloot-" + libloot::version() + "-" + "win64";
- }
-
- url source_url()
- {
- return "https://github.com/loot/libloot/releases/download/" +
- libloot::version() + "/" + release_name() + ".7z";
- }
-
- } // namespace
-
- libloot::libloot() : basic_task("libloot") {}
-
- std::string libloot::version()
- {
- return conf().version().get("libloot");
- }
-
- bool libloot::prebuilt()
- {
- return false;
- }
-
- fs::path libloot::source_path()
- {
- return conf().path().build() / release_name();
- }
-
- void libloot::do_clean(clean c)
- {
- // delete download
- if (is_set(c, clean::redownload))
- run_tool(downloader(source_url(), downloader::clean));
-
- // delete the whole directory
- if (is_set(c, clean::reextract)) {
- cx().trace(context::reextract, "deleting {}", source_path());
- op::delete_directory(cx(), source_path(), op::optional);
- }
- }
-
- void libloot::do_fetch()
- {
- const auto file = run_tool(downloader(source_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void libloot::do_build_and_install()
- {
- // copy dll
- op::copy_file_to_dir_if_better(cx(), source_path() / "bin" / "loot.dll",
- conf().path().install_loot());
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/lz4.cpp b/src/tasks/lz4.cpp
deleted file mode 100644
index 281ca7d..0000000
--- a/src/tasks/lz4.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-#include "pch.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- namespace {
-
- fs::path solution_dir()
- {
- return lz4::source_path() / "build" / "VS2022";
- }
-
- fs::path solution_file()
- {
- return solution_dir() / "lz4.sln";
- }
-
- fs::path out_dir()
- {
- return solution_dir() / "bin" / "x64_Release";
- }
-
- url prebuilt_url()
- {
- return make_prebuilt_url("lz4_prebuilt_" + lz4::version() + ".7z");
- }
-
- } // namespace
-
- lz4::lz4() : basic_task("lz4") {}
-
- std::string lz4::version()
- {
- return conf().version().get("lz4");
- }
-
- bool lz4::prebuilt()
- {
- return conf().prebuilt().get("lz4");
- }
-
- fs::path lz4::source_path()
- {
- return conf().path().build() / ("lz4-" + version());
- }
-
- void lz4::do_clean(clean c)
- {
- if (prebuilt()) {
- // delete download
- if (is_set(c, clean::redownload))
- run_tool(downloader(prebuilt_url(), downloader::clean));
-
- // delete the whole directory
- if (is_set(c, clean::reextract)) {
- cx().trace(context::reextract, "deleting {}", source_path());
- op::delete_directory(cx(), source_path(), op::optional);
- }
- }
- else {
- // delete the whole directory
- if (is_set(c, clean::reclone)) {
- git_wrap::delete_directory(cx(), source_path());
-
- // no point in doing anything more
- return;
- }
-
- // msbuild clean
- if (is_set(c, clean::rebuild))
- run_tool(create_msbuild_tool(msbuild::clean));
- }
- }
-
- void lz4::do_fetch()
- {
- if (prebuilt())
- fetch_prebuilt();
- else
- fetch_from_source();
- }
-
- void lz4::do_build_and_install()
- {
- if (prebuilt())
- build_and_install_prebuilt();
- else
- build_and_install_from_source();
- }
-
- void lz4::fetch_prebuilt()
- {
- cx().trace(context::generic, "using prebuilt lz4");
-
- const auto file = run_tool(downloader(prebuilt_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void lz4::build_and_install_prebuilt()
- {
- // copy pdb and dll
-
- op::copy_file_to_dir_if_better(cx(), source_path() / "bin" / "liblz4.pdb",
- conf().path().install_pdbs());
-
- op::copy_file_to_dir_if_better(cx(), source_path() / "bin" / "liblz4.dll",
- conf().path().install_dlls());
- }
-
- void lz4::fetch_from_source()
- {
- // clone
- run_tool(make_git()
- .url(make_git_url("lz4", "lz4"))
- .branch(version())
- .root(source_path()));
- }
-
- void lz4::build_and_install_from_source()
- {
- run_tool(create_msbuild_tool());
-
- // cmake_common looks for the lib files in the bin/ directory, which is
- // correct for prebuilts, but not from source, so copy the files in there
- op::copy_glob_to_dir_if_better(cx(), out_dir() / "*", source_path() / "bin",
- op::copy_files);
-
- // copy dll and pdb
- op::copy_file_to_dir_if_better(cx(), source_path() / "bin" / "liblz4.dll",
- conf().path().install_dlls());
-
- op::copy_file_to_dir_if_better(cx(), source_path() / "bin" / "liblz4.pdb",
- conf().path().install_pdbs());
- }
-
- msbuild lz4::create_msbuild_tool(msbuild::ops o)
- {
- return std::move(msbuild(o).solution(solution_file()).targets({"liblz4-dll"}));
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/modorganizer.cpp b/src/tasks/modorganizer.cpp
index c7947c7..139027d 100644
--- a/src/tasks/modorganizer.cpp
+++ b/src/tasks/modorganizer.cpp
@@ -59,18 +59,18 @@ namespace mob::tasks {
g.init_repo();
}
- modorganizer::modorganizer(std::string long_name, flags f)
- : modorganizer(std::vector{long_name}, f)
+ modorganizer::modorganizer(std::string long_name)
+ : modorganizer(std::vector{long_name})
{
}
- modorganizer::modorganizer(std::vector names, flags f)
- : modorganizer(std::vector(names.begin(), names.end()), f)
+ modorganizer::modorganizer(std::vector names)
+ : modorganizer(std::vector(names.begin(), names.end()))
{
}
- modorganizer::modorganizer(std::vector names, flags f)
- : task(make_names(names)), repo_(names[0]), flags_(f)
+ modorganizer::modorganizer(std::vector names)
+ : task(make_names(names)), repo_(names[0])
{
if (names.size() > 1) {
project_ = names[1];
@@ -80,14 +80,11 @@ namespace mob::tasks {
}
}
- bool modorganizer::is_gamebryo_plugin() const
+ std::string modorganizer::cmake_prefix_path()
{
- return is_set(flags_, gamebryo);
- }
-
- bool modorganizer::is_nuget_plugin() const
- {
- return is_set(flags_, nuget);
+ return conf().path().qt_install().string() + ";" +
+ (modorganizer::super_path() / "cmake_common").string() + ";" +
+ (conf().path().install() / "lib" / "cmake").string();
}
fs::path modorganizer::source_path() const
@@ -96,18 +93,9 @@ namespace mob::tasks {
return super_path() / name();
}
- fs::path modorganizer::project_file_path() const
- {
- // ask cmake for the build path it would use
- const auto build_path = create_cmake_tool(source_path()).build_path();
-
- // use the INSTALL project
- return build_path / (project_ + ".sln");
- }
-
fs::path modorganizer::super_path()
{
- return conf().path().build() / "modorganizer_super";
+ return conf().path().build();
}
url modorganizer::git_url() const
@@ -137,11 +125,7 @@ namespace mob::tasks {
// cmake clean
if (is_set(c, clean::reconfigure))
- run_tool(create_cmake_tool(cmake::clean));
-
- // msbuild clean
- if (is_set(c, clean::rebuild))
- run_tool(create_msbuild_tool(msbuild::clean));
+ run_tool(cmake(cmake::clean).root(source_path()));
}
void modorganizer::do_fetch()
@@ -165,7 +149,7 @@ namespace mob::tasks {
void modorganizer::do_build_and_install()
{
- // adds a git submodule in modorganizer_super for this project; note that
+ // adds a git submodule in build for this project; note that
// git_submodule_adder runs a thread because adding submodules is slow, but
// can happen while stuff is building
git_submodule_adder::instance().queue(
@@ -177,66 +161,44 @@ namespace mob::tasks {
// not all modorganizer projects need to actually be built, such as
// cmake_common, so don't try if there's no cmake file
- if (!fs::exists(source_path() / "CMakeLists.txt")) {
+ if (!exists(source_path() / "CMakeLists.txt")) {
cx().trace(context::generic, "{} has no CMakeLists.txt, not building",
repo_);
return;
}
+ // if there is a CMakeLists.txt, there must be a CMakePresets.json otherwise
+ // we cannot build
+ if (!exists(source_path() / "CMakePresets.json")) {
+ gcx().bail_out(context::generic,
+ "{} has no CMakePresets.txt, aborting build", repo_);
+ }
+
// run cmake
- run_tool(create_cmake_tool());
+ run_tool(cmake(cmake::generate)
+ .generator(cmake::vs)
+ .def("CMAKE_INSTALL_PREFIX:PATH", conf().path().install())
+ .def("CMAKE_PREFIX_PATH", cmake_prefix_path())
+ .configuration_types({task_conf().configuration()})
+ .preset("vs2022-windows")
+ .root(source_path()));
- // run restore for nuget
- //
- // until https://gitlab.kitware.com/cmake/cmake/-/issues/20646 is resolved,
- // we need a manual way of running the msbuild -t:restore
- if (is_nuget_plugin())
- run_tool(create_msbuild_tool().targets({"restore"}));
+ // run cmake --build with default target
+ // TODO: handle rebuild by adding `--clean-first`
+ // TODO: have a way to specify the `--parallel` value - 16 is useful to build
+ // game_bethesda that has 15 games, so 15 projects
+ run_tool(cmake(cmake::build)
+ .root(source_path())
+ .arg("--parallel")
+ .arg("16")
+ .configuration(task_conf().configuration()));
- // run msbuild
- run_tool(create_msbuild_tool());
- }
-
- cmake modorganizer::create_cmake_tool(cmake::ops o)
- {
- return create_cmake_tool(source_path(), o, task_conf().configuration());
- }
-
- cmake modorganizer::create_cmake_tool(const fs::path& root, cmake::ops o, config c)
- {
- return std::move(
- cmake(o)
- .generator(cmake::vs)
- .def("CMAKE_INSTALL_PREFIX:PATH", conf().path().install())
- .def("DEPENDENCIES_DIR", conf().path().build())
- .def("BOOST_ROOT", boost::source_path())
- .def("BOOST_LIBRARYDIR", boost::lib_path(arch::x64))
- .def("Boost_DIR", boost::cmake_path(arch::x64))
- .def("SPDLOG_ROOT", spdlog::source_path())
- .def("LOOT_PATH", libloot::source_path())
- .def("LZ4_ROOT", lz4::source_path())
- .def("QT_ROOT", qt::installation_path())
- .def("ZLIB_ROOT", zlib::source_path())
- .def("PYTHON_ROOT", python::source_path())
- .def("SEVENZ_ROOT", sevenz::source_path())
- .def("LIBBSARCH_ROOT", libbsarch::source_path())
- .def("BOOST_DI_ROOT", boost_di::source_path())
- // gtest has no RelWithDebInfo, so simply use Debug/Release
- .def("GTEST_ROOT",
- gtest::build_path(arch::x64, c == config::debug ? config::debug
- : config::release))
- .def("OPENSSL_ROOT_DIR", openssl::source_path())
- .def("DIRECTXTEX_ROOT", directxtex::source_path())
- .root(root));
- }
-
- msbuild modorganizer::create_msbuild_tool(msbuild::ops o)
- {
- return std::move(msbuild(o)
- .solution(project_file_path())
- .configuration(task_conf().configuration())
- .architecture(arch::x64));
+ // run cmake --install
+ run_tool(cmake(cmake::build)
+ .root(source_path())
+ .targets("INSTALL")
+ .configuration(task_conf().configuration()));
}
} // namespace mob::tasks
diff --git a/src/tasks/openssl.cpp b/src/tasks/openssl.cpp
deleted file mode 100644
index 5b1f502..0000000
--- a/src/tasks/openssl.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-#include "pch.h"
-#include "../core/process.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- namespace {
-
- url source_url()
- {
- return "https://www.openssl.org/source/"
- "openssl-" +
- openssl::version() + ".tar.gz";
- }
-
- url prebuilt_url()
- {
- return make_prebuilt_url("openssl-prebuilt-" + openssl::version() + ".7z");
- }
-
- std::string version_no_patch_underscores(bool primaryOnly = true)
- {
- auto v = openssl::parsed_version();
-
- std::string s = v.major;
-
- if (v.minor != "" && !primaryOnly)
- s += "_" + v.minor;
-
- return s;
- }
-
- // the filenames of the dlls, but without extension, because this is used for
- // both dlls and pdbs
- //
- std::vector output_names()
- {
- return {"libcrypto-" + version_no_patch_underscores() + "-x64",
- "libssl-" + version_no_patch_underscores() + "-x64"};
- }
-
- } // namespace
-
- openssl::openssl() : basic_task("openssl") {}
-
- std::string openssl::version()
- {
- return conf().version().get("openssl");
- }
-
- bool openssl::prebuilt()
- {
- return conf().prebuilt().get("openssl");
- }
-
- fs::path openssl::source_path()
- {
- return conf().path().build() / ("openssl-" + version());
- }
-
- fs::path openssl::build_path()
- {
- return source_path() / "build";
- }
-
- fs::path openssl::bin_path()
- {
- return build_path() / "bin";
- }
-
- void openssl::do_clean(clean c)
- {
- if (prebuilt()) {
- // delete prebuilt download
- if (is_set(c, clean::redownload))
- run_tool(downloader(prebuilt_url(), downloader::clean));
- }
- else {
- // delete source download
- if (is_set(c, clean::redownload))
- run_tool(downloader(source_url(), downloader::clean));
- }
-
- // there's no easy way to clean anything for openssl, it puts files all
- // over the place, just delete the whole thing
- if (is_any_set(c, clean::reextract | clean::reconfigure | clean::rebuild)) {
- cx().trace(context::reextract, "deleting {}", source_path());
- op::delete_directory(cx(), source_path(), op::optional);
- }
- }
-
- void openssl::do_fetch()
- {
- if (prebuilt())
- fetch_prebuilt();
- else
- fetch_from_source();
- }
-
- void openssl::do_build_and_install()
- {
- if (prebuilt())
- build_and_install_prebuilt();
- else
- build_and_install_from_source();
- }
-
- void openssl::fetch_prebuilt()
- {
- cx().trace(context::generic, "using prebuilt openssl");
-
- const auto file = run_tool(downloader(prebuilt_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void openssl::fetch_from_source()
- {
- const auto file = run_tool(downloader(source_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void openssl::build_and_install_prebuilt()
- {
- // nothing to built for prebuilt, just copy
- copy_files();
- }
-
- void openssl::build_and_install_from_source()
- {
- // running the Configure perl script generates a file `makefile`; since
- // Configuring takes forever and will fully run every time, don't run it if
- // the makefile already exists
- if (fs::exists(source_path() / "makefile"))
- cx().trace(context::bypass, "openssl already configured");
- else
- configure();
-
- // run the install_engines target in the makefile, this builds everything
- // required
- install_engines();
-
- // applink.c is required when building python from source, the .vcxproj
- // assumes it's in the include path for whatever reason, so copy it there
- op::copy_file_to_dir_if_better(cx(), source_path() / "ms" / "applink.c",
- include_path());
-
- copy_files();
- }
-
- void openssl::configure()
- {
- run_tool(process_runner(process()
- .binary(perl::binary())
- .arg("Configure")
- .arg("VC-WIN64A")
- .arg("--openssldir=", build_path())
- .arg("--prefix=", build_path())
- .arg("-FS")
- .arg("-MP1")
- .arg("-wd4566")
- .cwd(source_path())
- .env(env::vs(arch::x64))));
- }
-
- void openssl::install_engines()
- {
- build_loop(cx(), [&](bool mp) {
- // jom defaults to multiprocess, give allow_failure for multiprocess
- // builds and force single_job for the last single process build
-
- const int exit_code =
- run_tool(jom()
- .path(source_path())
- .target("install_engines")
- .flag(mp ? jom::allow_failure : jom::single_job));
-
- return (exit_code == 0);
- });
- }
-
- void openssl::copy_files()
- {
- // duplicate the dlls to both bin/ and bin/dlls, they're needed by both
- // MO and Qt
- copy_dlls_to(conf().path().install_bin());
- copy_dlls_to(conf().path().install_dlls());
-
- // pdbs
- copy_pdbs_to(conf().path().install_pdbs());
- }
-
- void openssl::copy_dlls_to(const fs::path& dir)
- {
- for (auto&& name : output_names()) {
- op::copy_file_to_dir_if_better(cx(), bin_path() / (name + ".dll"), dir);
- }
- }
-
- void openssl::copy_pdbs_to(const fs::path& dir)
- {
- for (auto&& name : output_names()) {
- op::copy_file_to_dir_if_better(cx(), bin_path() / (name + ".pdb"), dir);
- }
- }
-
- fs::path openssl::include_path()
- {
- return openssl::source_path() / "include";
- }
-
- openssl::version_info openssl::parsed_version()
- {
- // 1.2.3d
- // everything but 1 is optional
- std::regex re("(\\d+)" // 1
- "(?:" //
- "\\.(\\d+)" // .2
- "(?:" //
- "\\.(\\d+)([a-zA-Z]+)?" // .3d
- ")?" //
- ")?");
-
- std::smatch m;
-
- const auto s = version();
-
- if (!std::regex_match(s, m, re))
- gcx().bail_out(context::generic, "bad openssl version '{}'", s);
-
- return {m[1], m[2], m[3]};
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/pybind11.cpp b/src/tasks/pybind11.cpp
deleted file mode 100644
index 82edd10..0000000
--- a/src/tasks/pybind11.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "pch.h"
-#include "../core/process.h"
-#include "tasks.h"
-
-// see the top of pyqt.cpp for some stuff about python/sip/pyqt
-
-namespace mob::tasks {
-
- pybind11::pybind11() : basic_task("pybind11") {}
-
- bool pybind11::prebuilt()
- {
- // header only available
- return true;
- }
-
- std::string pybind11::version()
- {
- return conf().version().get("pybind11");
- }
-
- fs::path pybind11::source_path()
- {
- return conf().path().build() / "pybind11";
- }
-
- void pybind11::do_clean(clean c)
- {
- if (is_set(c, clean::reclone)) {
- git_wrap::delete_directory(cx(), source_path());
- return;
- }
- }
-
- void pybind11::do_fetch()
- {
- run_tool(make_git()
- .url(make_git_url("pybind", "pybind11"))
- .branch(version())
- .root(source_path()));
- }
-
- void pybind11::do_build_and_install() {}
-} // namespace mob::tasks
diff --git a/src/tasks/pyqt.cpp b/src/tasks/pyqt.cpp
deleted file mode 100644
index fd62421..0000000
--- a/src/tasks/pyqt.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-#include "pch.h"
-#include "../core/process.h"
-#include "tasks.h"
-
-// build process for python, sip and pyqt; if one is built from source, all
-// three need to be built from source, plus openssl because python needs it
-//
-// 1) build openssl
-//
-// 2) build python, needs openssl
-//
-// 3) build sip, needs python:
-// - download and extract source archive
-// - run `python setup.py install` in sip's directory, this generates
-// sip-install.exe and sip-module.exe in python-XX/Scripts (among others)
-// - run `sip-module.exe --sip-h` to generate a sip.h file in sip's source
-// directory
-// - that header file is copied into python/include and is included by
-// by plugin_python in sipapiaccess.h
-//
-// 4) build pyqt, needs sip
-// - download and extract source archive
-// - use `pip install` to install PyQt-builder
-// - run `sip-install.exe` with the list of required modules, creating a
-// folder for each module in PyQt6-XX/build/ with `.pyd` files
-// - run `sip-module.exe --sdist`, which creates
-// downloads/PyQt6_sip-XXX.tar.gz
-// - run `pip install` with that file, which creates
-// `python-XX/Lib/site-packages/PyQt6/sip.cp32-win_amd64.pyd`
-// - for installation, a bunch of files from site-packages/PyQt6/ are
-// copied into install/bin/plugins/data/PyQt6, including a .pyi file from
-// sip
-
-namespace mob::tasks {
-
- namespace {
-
- url source_url()
- {
- const auto version = pyqt::version();
- std::string base = "https://pypi.io/packages/source/p/pyqt6/";
- if (version.find("dev") != std::string::npos) {
- base = "https://riverbankcomputing.com/pypi/packages/PyQt6/";
- }
- return base + "pyqt6-" + pyqt::version() + ".tar.gz";
- }
-
- url prebuilt_url()
- {
- return make_prebuilt_url(
- "PyQt6_gpl-prebuilt-" + pyqt::version() +
- (pyqt::build_type() == config::debug ? "-debug" : "") + ".7z");
- }
-
- // file created by sip-module.exe
- //
- fs::path sip_install_file()
- {
- return "PyQt6_sip-" + sip::version_for_pyqt() + ".tar.gz";
- }
-
- } // namespace
-
- pyqt::pyqt() : basic_task("pyqt") {}
-
- std::string pyqt::version()
- {
- return conf().version().get("pyqt");
- }
-
- std::string pyqt::builder_version()
- {
- return conf().version().get("pyqt_builder");
- }
-
- bool pyqt::prebuilt()
- {
- return conf().prebuilt().get("pyqt");
- }
-
- fs::path pyqt::source_path()
- {
- return conf().path().build() / ("pyqt6-" + version());
- }
-
- fs::path pyqt::build_path()
- {
- return source_path() / "build";
- }
-
- config pyqt::build_type()
- {
- return conf().build_types().get("pyqt");
- }
-
- std::string pyqt::pyqt_sip_module_name()
- {
- return "PyQt6.sip";
- }
-
- void pyqt::do_clean(clean c)
- {
- if (prebuilt()) {
- // delete prebuilt download
- if (is_set(c, clean::redownload))
- run_tool(downloader(prebuilt_url(), downloader::clean));
- }
- else {
- // delete source download
- if (is_set(c, clean::redownload))
- run_tool(downloader(source_url(), downloader::clean));
- }
-
- // delete whole directory
- if (is_set(c, clean::reextract)) {
- cx().trace(context::reextract, "deleting {}", source_path());
- op::delete_directory(cx(), source_path(), op::optional);
-
- // no need to do anything else
- return;
- }
-
- if (!prebuilt()) {
- // delete the pyqt-sip file that's created when building from source
- if (is_set(c, clean::rebuild)) {
- op::delete_file(cx(), conf().path().cache() / sip_install_file(),
- op::optional);
- }
- }
- }
-
- void pyqt::do_fetch()
- {
- if (prebuilt())
- fetch_prebuilt();
- else
- fetch_from_source();
- }
-
- void pyqt::do_build_and_install()
- {
- if (prebuilt())
- build_and_install_prebuilt();
- else
- build_and_install_from_source();
- }
-
- void pyqt::fetch_prebuilt()
- {
- const auto file = run_tool(downloader(prebuilt_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void pyqt::build_and_install_prebuilt()
- {
- // copy the prebuilt files directly into the python directory, they're
- // required by sip, which is always built from source
- op::copy_glob_to_dir_if_better(cx(), source_path() / "*", python::source_path(),
- op::copy_files | op::copy_dirs);
-
- // copy files to build/install for MO
- copy_files();
- }
-
- void pyqt::fetch_from_source()
- {
- const auto file = run_tool(downloader(source_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void pyqt::build_and_install_from_source()
- {
- // use pip to install the pyqt builder
- if (python::build_type() == config::debug) {
- // PyQt-builder has sip as a dependency, so installing it directly will
- // replace the sip we have installed manually, but the installed sip will
- // not work (see comment in sip::build() for details)
- //
- // the workaround is to install the dependencies manually (only packaging),
- // and then use a --no-dependencies install with pip
- //
- run_tool(pip(pip::install).package("packaging"));
- run_tool(pip(pip::install)
- .package("PyQt-builder")
- .no_dependencies()
- .version(builder_version()));
- }
- else {
- run_tool(
- pip(pip::install).package("PyQt-builder").version(builder_version()));
- }
-
- // patch for builder.py
- run_tool(patcher()
- .task(name())
- .file("builder.py.manual_patch")
- .root(python::site_packages_path() / "pyqtbuild"));
-
- // build modules and generate the PyQt6_sip-XX.tar.gz file
- sip_build();
-
- // run pip install for the PyQt6_sip-XX.tar.gz file
- install_sip_file();
-
- // copy files to build/install for MO
- copy_files();
- }
-
- void pyqt::sip_build()
- {
- // put qt and python in the path, set CL and LIB, which are used by the
- // visual c++ compiler that's eventually spawned, and set PYTHONHOME
- auto pyqt_env =
- env::vs_x64()
- .append_path({qt::bin_path(), python::build_path(),
- python::source_path(), python::scripts_path()})
- .set("CL", " /MP")
- .set("LIB", ";" + path_to_utf8(conf().path().install_libs()),
- env::append)
- .set("PYTHONHOME", path_to_utf8(python::source_path()));
-
- // create a bypass file, because pyqt always tries to build stuff and it
- // takes forever
- bypass_file built_bypass(cx(), source_path(), "built");
-
- if (built_bypass.exists()) {
- cx().trace(context::bypass, "pyqt already built");
- }
- else {
- // sip-install.exe has trouble with deleting the build/ directory and
- // trying to recreate it too fast, giving an access denied error; do it
- // here instead
- op::delete_directory(cx(), source_path() / "build", op::optional);
-
- // 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)));
-
- // 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())
- .arg("--sdist")
- .arg(pyqt_sip_module_name())
- .cwd(conf().path().cache())
- .env(pyqt_env)));
- }
-
- void pyqt::install_sip_file()
- {
- // create a bypass file, because pyqt always tries to install stuff and it
- // takes forever
- bypass_file installed_bypass(cx(), source_path(), "installed");
-
- if (installed_bypass.exists()) {
- cx().trace(context::bypass, "pyqt already installed");
- }
- else {
- if (python::build_type() == config::debug) {
-
- const auto pyqt_sip_folder = source_path() / "PyQt6_sip" /
- ("pyqt6_sip-" + sip::version_for_pyqt());
-
- // in debug, we need to do stuff manually because pip does not work
- // as expected
- run_tool(extractor()
- .file(conf().path().cache() / sip_install_file())
- .output(pyqt_sip_folder.parent_path()));
-
- run_tool(mob::python()
- .root(pyqt_sip_folder)
- .arg("setup.py")
- .arg("build")
- .arg("--debug"));
-
- run_tool(pip(pip::install).file(pyqt_sip_folder));
- }
- else {
- // run `pip install` on the generated PyQt6_sip-XX.tar.gz file
- run_tool(
- pip(pip::install).file(conf().path().cache() / sip_install_file()));
- }
-
- // done, create the bypass file
- installed_bypass.create();
- }
- }
-
- void pyqt::copy_files()
- {
- // pyqt puts its files in python-XX/Lib/site-packages/PyQt6
- const fs::path site_packages_pyqt = python::site_packages_path() / "PyQt6";
-
- // copying some dlls from Qt's installation directory into
- // python-XX/PCBuild/amd64, those are needed by PyQt6 when building several
- // projects
-
- const std::vector dlls{"Qt6Core", "Qt6Xml"};
-
- 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
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/python.cpp b/src/tasks/python.cpp
deleted file mode 100644
index b70d804..0000000
--- a/src/tasks/python.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-#include "pch.h"
-#include "../core/process.h"
-#include "tasks.h"
-
-// see the top of pyqt.cpp for some stuff about python/sip/pyqt
-
-namespace mob::tasks {
-
- namespace {
-
- std::string version_without_v()
- {
- const auto v = python::parsed_version();
-
- // 3.8.1
- std::string s = v.major + "." + v.minor;
- if (v.patch != "")
- s += "." + v.patch;
-
- return s;
- }
-
- std::string version_for_dll()
- {
- const auto v = python::parsed_version();
-
- // 38
- return v.major + v.minor;
- }
-
- url prebuilt_url()
- {
- return make_prebuilt_url(
- "python-prebuilt-" + version_without_v() +
- (python::build_type() == config::debug ? "-debug" : "") + ".7z");
- }
-
- fs::path solution_file()
- {
- return python::source_path() / "PCBuild" / "pcbuild.sln";
- }
-
- fs::path python_core_zip_file()
- {
- return python::build_path() / "pythoncore" /
- ("python" + version_for_dll() + ".zip");
- }
-
- } // namespace
-
- python::python() : basic_task("python") {}
-
- std::string python::version()
- {
- return conf().version().get("python");
- }
-
- bool python::prebuilt()
- {
- return conf().prebuilt().get("python");
- }
-
- python::version_info python::parsed_version()
- {
- // v3.8.1
- // v and .1 are optional
- std::regex re(R"(v?(\d+)\.(\d+)(?:\.(\d+))?)");
- std::smatch m;
-
- const auto s = version();
-
- if (!std::regex_match(s, m, re))
- gcx().bail_out(context::generic, "bad python version '{}'", s);
-
- version_info v;
-
- v.major = m[1];
- v.minor = m[2];
- v.patch = m[3];
-
- return v;
- }
-
- fs::path python::source_path()
- {
- return conf().path().build() / ("python-" + version_without_v());
- }
-
- fs::path python::build_path()
- {
- return source_path() / "PCBuild" / "amd64";
- }
-
- config python::build_type()
- {
- return conf().build_types().get("python");
- }
-
- void python::do_clean(clean c)
- {
- if (prebuilt()) {
- // delete download
- if (is_set(c, clean::redownload))
- run_tool(downloader(prebuilt_url(), downloader::clean));
-
- // delete the whole directory
- if (is_set(c, clean::reextract)) {
- cx().trace(context::reextract, "deleting {}", source_path());
- op::delete_directory(cx(), source_path(), op::optional);
- }
- }
- else {
- // delete the whole directory
- if (is_set(c, clean::reclone)) {
- git_wrap::delete_directory(cx(), source_path());
-
- // no need to do anything else
- return;
- }
-
- // msbuild clean
- if (is_set(c, clean::rebuild))
- run_tool(create_msbuild_tool(msbuild::clean));
- }
- }
-
- void python::do_fetch()
- {
- if (prebuilt())
- fetch_prebuilt();
- else
- fetch_from_source();
- }
-
- void python::do_build_and_install()
- {
- if (prebuilt())
- build_and_install_prebuilt();
- else
- build_and_install_from_source();
- }
-
- void python::fetch_prebuilt()
- {
- const auto file = run_tool(downloader(prebuilt_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void python::build_and_install_prebuilt()
- {
- install_pip();
- copy_files();
- }
-
- void python::fetch_from_source()
- {
- run_tool(make_git()
- .url(make_git_url("python", "cpython"))
- .branch(version())
- .root(source_path()));
- }
-
- void python::build_and_install_from_source()
- {
- // download externals
- prepare_dependencies();
-
- // build
- run_tool(create_msbuild_tool());
-
- // package stuff into pythoncore.zip
- package();
-
- // install pip for other tasks that need it
- install_pip();
-
- // boost.python expects pyconfig.h to be in the include path
- op::copy_file_to_dir_if_better(cx(), source_path() / "PC" / "pyconfig.h",
- include_path());
-
- copy_files();
- }
-
- void python::prepare_dependencies()
- {
- const auto bat = source_path() / "PCBuild" / "get_externals.bat";
- run_tool(process_runner(process().binary(bat).cwd(source_path())));
- }
-
- void python::package()
- {
- if (fs::exists(python_core_zip_file())) {
- cx().trace(context::bypass, "python already packaged");
- return;
- }
-
- 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(p));
- }
-
- void python::copy_files()
- {
- // libs
- op::copy_glob_to_dir_if_better(cx(), build_path() / "*.lib",
- conf().path().install_libs(), op::copy_files);
-
- // pdbs
- op::copy_file_to_dir_if_better(
- 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
- }
-
- void python::install_pip()
- {
- cx().trace(context::generic, "installing pip");
- run_tool(pip(pip::ensure));
- }
-
- msbuild python::create_msbuild_tool(msbuild::ops o)
- {
- return std::move(
- msbuild(o)
- .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()),
- "opensslIncludeDir=" + path_to_utf8(openssl::include_path()),
- "opensslOutDir=" + path_to_utf8(openssl::source_path())}));
- }
-
- fs::path python::python_exe()
- {
- return build_path() /
- (build_type() == config::debug ? "python_d.exe" : "python.exe");
- }
-
- fs::path python::include_path()
- {
- return source_path() / "Include";
- }
-
- fs::path python::scripts_path()
- {
- return source_path() / "Scripts";
- }
-
- fs::path python::site_packages_path()
- {
- return source_path() / "Lib" / "site-packages";
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/sevenz.cpp b/src/tasks/sevenz.cpp
deleted file mode 100644
index f552508..0000000
--- a/src/tasks/sevenz.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-#include "pch.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- namespace {
-
- std::string version_for_url()
- {
- return replace_all(sevenz::version(), ".", "");
- }
-
- url source_url()
- {
- return "https://www.7-zip.org/a/7z" + version_for_url() + "-src.7z";
- }
-
- // 7z has a bunch of modules, like the gui, etc., just build the dll
- //
- fs::path module_to_build()
- {
- return sevenz::source_path() / "CPP" / "7zip" / "Bundles" / "Format7zF";
- }
-
- } // namespace
-
- sevenz::sevenz() : basic_task("7z", "sevenz") {}
-
- std::string sevenz::version()
- {
- return conf().version().get("sevenz");
- }
-
- bool sevenz::prebuilt()
- {
- return false;
- }
-
- fs::path sevenz::source_path()
- {
- return conf().path().build() / ("7zip-" + version());
- }
-
- void sevenz::do_clean(clean c)
- {
- // delete download
- if (is_set(c, clean::redownload))
- run_tool(downloader(source_url(), downloader::clean));
-
- // delete whole directory
- if (is_set(c, clean::reextract)) {
- cx().trace(context::reextract, "deleting {}", source_path());
- op::delete_directory(cx(), source_path(), op::optional);
-
- // no need to do anything else
- return;
- }
-
- // delete whole output directory
- if (is_set(c, clean::rebuild))
- op::delete_directory(cx(), module_to_build() / "x64", op::optional);
- }
-
- void sevenz::do_fetch()
- {
- const auto file = run_tool(downloader(source_url()));
-
- run_tool(extractor().file(file).output(source_path()));
- }
-
- void sevenz::do_build_and_install()
- {
- build();
-
- // copy 7z.dll to install/bin/dlls
- op::copy_file_to_dir_if_better(cx(), module_to_build() / "x64/7z.dll",
- conf().path().install_dlls());
- }
-
- void sevenz::build()
- {
- build_loop(cx(), [&](bool mp) {
- const int exit_code = run_tool(nmake()
- .path(module_to_build())
- .def("CPU=x64")
- .def("NEW_COMPILER=1")
- .def("MY_STATIC_LINK=1")
- .def("NO_BUFFEROVERFLOWU=1"));
-
- return (exit_code == 0);
- });
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/sip.cpp b/src/tasks/sip.cpp
deleted file mode 100644
index aed6e34..0000000
--- a/src/tasks/sip.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-#include "pch.h"
-#include "../core/process.h"
-#include "tasks.h"
-
-// see the top of pyqt.cpp for some stuff about python/sip/pyqt
-
-namespace mob::tasks {
-
- namespace {
-
- fs::path download_file()
- {
- return conf().path().cache() / ("sip-" + sip::version() + ".tar.gz");
- }
-
- std::string version_for_module_source()
- {
- // 12.7.2
- // .2 is optional
- std::regex re(R"((\d+)\.(\d+)(?:\.(\d+))?)");
- std::smatch m;
-
- const auto s = sip::version_for_pyqt();
-
- if (!std::regex_match(s, m, re))
- gcx().bail_out(context::generic, "bad pyqt sip version {}", s);
-
- // 12.7
- return m[1].str(); // + "." + m[2].str();
- }
-
- // header file generated by `sip-module.exe` at the end of the build process,
- // used as a bypass file and also copied into python's include directory,
- // plugin_python needs it
- //
- fs::path sip_header_file()
- {
- return sip::source_path() / "sip.h";
- }
-
- } // namespace
-
- sip::sip() : basic_task("sip") {}
-
- std::string sip::version()
- {
- return conf().version().get("sip");
- }
-
- std::string sip::version_for_pyqt()
- {
- return conf().version().get("pyqt_sip");
- }
-
- bool sip::prebuilt()
- {
- return false;
- }
-
- fs::path sip::source_path()
- {
- return conf().path().build() / ("sip-" + version());
- }
-
- fs::path sip::sip_module_exe()
- {
- return python::scripts_path() / "sip-module.exe";
- }
-
- fs::path sip::sip_install_exe()
- {
- return python::scripts_path() / "sip-install.exe";
- }
-
- fs::path sip::module_source_path()
- {
- // 12.7
- const auto dir = version_for_module_source();
-
- return source_path() / "sipbuild" / "module" / "source" / dir;
- }
-
- void sip::do_clean(clean c)
- {
- // delete file downloaded by pip
- if (is_set(c, clean::redownload)) {
- if (fs::exists(download_file())) {
- cx().trace(context::redownload, "deleting {}", download_file());
- op::delete_file(cx(), download_file(), op::optional);
- }
- }
-
- // delete the whole thing
- if (is_set(c, clean::reextract)) {
- cx().trace(context::reextract, "deleting {}", source_path());
- op::delete_directory(cx(), source_path(), op::optional);
- }
-
- // delete the whole build directory
- if (is_set(c, clean::rebuild)) {
- op::delete_directory(cx(), source_path() / "build", op::optional);
-
- if (fs::exists(sip_header_file()))
- op::delete_file(cx(), sip_header_file(), op::optional);
- }
-
- // note that there's a bunch of files still left python-XX/Scripts that
- // can't be easily deleted except by deleting something like "sip-*", but
- // there might be other stuff in there
- }
-
- void sip::do_fetch()
- {
- if (fs::exists(download_file())) {
- cx().trace(context::bypass, "sip: {} already exists", download_file());
- }
- else {
- // download
- run_tool(pip(pip::download).package("sip").version(version()));
- }
-
- // extract
- run_tool(extractor().file(download_file()).output(source_path()));
- }
-
- void sip::do_build_and_install()
- {
- if (fs::exists(sip_header_file())) {
- cx().trace(context::bypass, "{} already exists", sip_header_file());
- }
- else {
- build();
- generate_header();
- }
-
- // sip.h is included by sipapiaccess.h in plugin_python and it assumes it's
- // in the include path
- op::copy_file_to_dir_if_better(cx(), sip_header_file(), python::include_path());
- }
-
- void sip::build()
- {
- 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(pip(pip::install).package("setuptools"));
- 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)
- {
- // all the various .py files that were installed in python-XX/Scripts/
- // by build() above have a shebang that has the absolute path to the python
- // executable
- //
- // these .py files are used by their corresponding .exe file, like
- // `sip-module.exe` calls into `sip-module.py`
- //
- // the files are encoded in utf-8, but the .exe's will fail to execute them
- // if they have non-ascii characters in the python path
- //
- // this converts the files into ACP, hoping that the characters actually
- // exist in the codepage, so that the .exe can run
- //
- // if the path contains utf-8 characters that don't exist in the ACP,
- // conversion will fail and U+FFFD will be written, but it would have failed
- // anyway
-
- const fs::path src = python::scripts_path() / filename;
- const fs::path backup = python::scripts_path() / (filename + ".bak");
- const fs::path dest = python::scripts_path() / (filename + ".acp");
-
- if (!fs::exists(backup)) {
- cx().debug(context::generic, "converting {} to acp", src);
-
- // read the utf8 file
- const std::string utf8 = op::read_text_file(cx(), encodings::utf8, src);
-
- // convert to acp and write to filename.acp
- op::write_text_file(cx(), encodings::acp, dest, utf8);
-
- // rename the source to .bak and rename filename.acp to the original
- op::replace_file(cx(), src, dest, backup);
- }
- }
-
- void sip::generate_header()
- {
- // generate sip.h, will be copied to python's include directory, used
- // by plugin_python
- run_tool(process_runner(process()
- .binary(sip_module_exe())
- .chcp(65001)
- .stdout_encoding(encodings::acp)
- .stderr_encoding(encodings::acp)
- .arg("--sip-h")
- .arg(pyqt::pyqt_sip_module_name())
- .cwd(source_path())));
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/spdlog.cpp b/src/tasks/spdlog.cpp
deleted file mode 100644
index 913c438..0000000
--- a/src/tasks/spdlog.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "pch.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- spdlog::spdlog() : basic_task("spdlog") {}
-
- std::string spdlog::version()
- {
- return conf().version().get("spdlog");
- }
-
- bool spdlog::prebuilt()
- {
- return false;
- }
-
- fs::path spdlog::source_path()
- {
- return conf().path().build() / ("spdlog-" + version());
- }
-
- void spdlog::do_clean(clean c)
- {
- // delete the whole directory
- if (is_set(c, clean::reclone))
- git_wrap::delete_directory(cx(), source_path());
- }
-
- void spdlog::do_fetch()
- {
- run_tool(make_git()
- .url(make_git_url("gabime", "spdlog"))
- .branch(version())
- .root(source_path()));
- }
-
-} // namespace mob::tasks
diff --git a/src/tasks/stylesheets.cpp b/src/tasks/stylesheets.cpp
index 0cc7691..a9df301 100644
--- a/src/tasks/stylesheets.cpp
+++ b/src/tasks/stylesheets.cpp
@@ -77,7 +77,7 @@ namespace mob::tasks {
fs::path stylesheets::release_build_path(const release& r) const
{
// something like build/paper-mono-v2.1
- return conf().path().build() / (r.repo + "-" + r.version);
+ return conf().path().build() / "stylesheets" / (r.repo + "-" + r.version);
}
downloader stylesheets::make_downloader_tool(const release& r,
diff --git a/src/tasks/task.cpp b/src/tasks/task.cpp
index 451366b..f8bd06c 100644
--- a/src/tasks/task.cpp
+++ b/src/tasks/task.cpp
@@ -391,13 +391,6 @@ namespace mob {
do_fetch();
check_interrupted();
-
- // auto patching if the task has a source path
- if (!get_source_path().empty()) {
- cx().debug(context::generic, "patching");
-
- run_tool(patcher().task(name(), get_prebuilt()).root(get_source_path()));
- }
}
void task::build_and_install()
@@ -413,6 +406,7 @@ namespace mob {
cx().info(context::generic, "build and install");
do_build_and_install();
+ cx().info(context::generic, "done");
}
void task::check_bailed()
diff --git a/src/tasks/tasks.h b/src/tasks/tasks.h
index 54afb97..bf76107 100644
--- a/src/tasks/tasks.h
+++ b/src/tasks/tasks.h
@@ -11,87 +11,6 @@ namespace mob::tasks {
// single header for all the tasks, not worth having a header per task
- class boost : public basic_task {
- public:
- struct version_info {
- std::string major, minor, patch, rest;
- };
-
- boost();
-
- static version_info parsed_version();
- static std::string version();
- static std::string version_vs();
- static bool prebuilt();
-
- static fs::path source_path();
- static fs::path cmake_path(arch a);
- static fs::path lib_path(arch a);
- static fs::path root_lib_path(arch a);
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
-
- private:
- void fetch_prebuilt();
- void build_and_install_prebuilt();
-
- void fetch_from_source();
- void build_and_install_from_source();
- void write_config_jam();
-
- void bootstrap();
-
- void do_b2(const std::vector& components, const std::string& link,
- const std::string& runtime_link, arch a);
- };
-
- // needed by bsapacker
- //
- class boost_di : public basic_task {
- public:
- boost_di();
-
- static std::string version();
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- };
-
- // needed by python
- //
- class bzip2 : public basic_task {
- public:
- bzip2();
-
- static std::string version();
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- };
-
- class directxtex : public basic_task {
- public:
- directxtex();
-
- static std::string version();
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
- };
-
class explorerpp : public basic_task {
public:
explorerpp();
@@ -105,21 +24,6 @@ namespace mob::tasks {
void do_fetch() override;
};
- class gtest : public basic_task {
- public:
- gtest();
-
- static std::string version();
- static bool prebuilt();
- static fs::path source_path();
- static fs::path build_path(arch = arch::x64, config = config::release);
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
- };
-
class installer : public basic_task {
public:
installer();
@@ -134,38 +38,6 @@ namespace mob::tasks {
void do_build_and_install() override;
};
- class libbsarch : public basic_task {
- public:
- libbsarch();
-
- static std::string version();
- static config build_type();
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
- };
-
- class libloot : public basic_task {
- public:
- libloot();
-
- static std::string version();
- static std::string hash();
- static std::string branch();
-
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
- };
-
class licenses : public task {
public:
licenses();
@@ -174,29 +46,6 @@ namespace mob::tasks {
void do_build_and_install() override;
};
- class lz4 : public basic_task {
- public:
- lz4();
-
- static std::string version();
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
-
- private:
- void fetch_prebuilt();
- void build_and_install_prebuilt();
-
- void fetch_from_source();
- void build_and_install_from_source();
-
- msbuild create_msbuild_tool(msbuild::ops o = msbuild::build);
- };
-
// a task for all modorganizer projects except for the installer, which is
// technically an MO project but is built differently
//
@@ -206,6 +55,10 @@ namespace mob::tasks {
//
class modorganizer : public task {
public:
+ // build CMAKE_PREFIX_PATH for MO2 tasks
+ //
+ static std::string cmake_prefix_path();
+
// path of the root modorganizer_super directory
//
static fs::path super_path();
@@ -217,34 +70,13 @@ namespace mob::tasks {
cmake::ops o = cmake::generate,
config config = config::relwithdebinfo);
- // flags for some MO projects
- enum flags {
- noflags = 0x00,
-
- // gamebryo project, used by the translations task because these
- // projects have multiple .ts files that have to be merged
- gamebryo = 0x01,
-
- // project that uses nuget, cmake doesn't support those right now, so
- // `msbuild -t:restore` has to be run manually
- nuget = 0x02,
- };
-
// some mo tasks have more than one name, mostly because the transifex slugs
// are different than the names on github; the std::string and const char*
// overloads are because they're constructed from initializer lists and it's
// more convenient that way
- modorganizer(std::string name, flags f = noflags);
- modorganizer(std::vector names, flags f = noflags);
- modorganizer(std::vector names, flags f = noflags);
-
- // whether this project has the gamebryo flag on
- //
- bool is_gamebryo_plugin() const;
-
- // whether this project has the nuget flag on
- //
- bool is_nuget_plugin() const;
+ modorganizer(std::string name);
+ modorganizer(std::vector names);
+ modorganizer(std::vector names);
// url to the git repo
//
@@ -272,261 +104,6 @@ namespace mob::tasks {
private:
std::string repo_;
std::string project_;
- flags flags_;
-
- // creates the cmake tool for this MO project
- //
- cmake create_cmake_tool(cmake::ops o = cmake::generate);
-
- // creates the msbuild tool for this MO project
- //
- msbuild create_msbuild_tool(msbuild::ops o = msbuild::build);
-
- // this is the file targeted by the msbuild tool
- //
- // it's not actually the .sln file because the cmake files have historically
- // been inconsistent in what the main project in the solution is and whether
- // the INSTALL project was enabled or not, so just building the .sln itself
- // might not actually build everything
- //
- // by targeting the INSTALL project directly, everything will always be
- // built correctly, regardless of how the solution file is generated
- //
- fs::path project_file_path() const;
- };
-
- class ncc : public basic_task {
- public:
- ncc();
-
- static std::string version();
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
-
- private:
- msbuild create_msbuild_tool(msbuild::ops o);
- };
-
- class nmm : public basic_task {
- public:
- nmm();
-
- static std::string version();
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
-
- private:
- msbuild create_msbuild_tool(msbuild::ops o = msbuild::build,
- msbuild::flags_t f = msbuild::noflags);
- };
-
- class openssl : public basic_task {
- public:
- struct version_info {
- std::string major, minor, patch;
- };
-
- openssl();
-
- static version_info parsed_version();
- static std::string version();
- static bool prebuilt();
-
- static fs::path source_path();
- static fs::path include_path();
- static fs::path build_path();
- static fs::path bin_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
-
- private:
- void fetch_prebuilt();
- void fetch_from_source();
- void build_and_install_prebuilt();
- void build_and_install_from_source();
-
- void configure();
- void install_engines();
- void copy_files();
- void copy_dlls_to(const fs::path& dir);
- void copy_pdbs_to(const fs::path& dir);
- };
-
- // when building from source, builds both pyqt5 and pyqt5-sip; when using the
- // prebuilt, the downloaded zip contains both
- //
- class pyqt : public basic_task {
- public:
- pyqt();
-
- static std::string version();
- static std::string builder_version();
- static bool prebuilt();
-
- static fs::path source_path();
- static fs::path build_path();
- static config build_type();
-
- // "PyQt5.sip", used both in pyqt and sip
- //
- static std::string pyqt_sip_module_name();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
-
- private:
- void fetch_prebuilt();
- void fetch_from_source();
- void build_and_install_prebuilt();
- void build_and_install_from_source();
-
- void sip_build();
- void install_sip_file();
- void copy_files();
- };
-
- class python : public basic_task {
- public:
- struct version_info {
- std::string major;
- std::string minor;
- std::string patch;
- };
-
- python();
-
- static std::string version();
- static bool prebuilt();
- static version_info parsed_version();
-
- // build/python-XX
- //
- static fs::path source_path();
-
- // build/python-XX/PCBuild/amd64
- //
- static fs::path build_path();
-
- // build/python-XX/PCBuild/amd64/python.exe
- //
- static fs::path python_exe();
-
- // build/python-XX/Include
- //
- static fs::path include_path();
-
- // build/python-XX/Scripts
- //
- static fs::path scripts_path();
-
- // build/python-XX/Lib/site-packages
- //
- static fs::path site_packages_path();
-
- // configuration to build
- //
- static config build_type();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
-
- private:
- void fetch_prebuilt();
- void fetch_from_source();
- void build_and_install_prebuilt();
- void build_and_install_from_source();
-
- void prepare_dependencies();
- void package();
- void install_pip();
- void copy_files();
-
- msbuild create_msbuild_tool(msbuild::ops o = msbuild::build);
- };
-
- class pybind11 : public basic_task {
- public:
- pybind11();
-
- static bool prebuilt();
- static std::string version();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
- };
-
- class sevenz : public basic_task {
- public:
- sevenz();
-
- static std::string version();
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
-
- private:
- void build();
- };
-
- class sip : public basic_task {
- public:
- sip();
-
- static std::string version();
- static std::string version_for_pyqt();
- static bool prebuilt();
-
- static fs::path source_path();
- static fs::path sip_module_exe();
- static fs::path sip_install_exe();
- static fs::path module_source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
-
- private:
- void build();
- void generate_header();
- void convert_script_file_to_acp(const std::string& filename);
- };
-
- class spdlog : public basic_task {
- public:
- spdlog();
-
- static std::string version();
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
};
class stylesheets : public task {
@@ -624,11 +201,6 @@ namespace mob::tasks {
// duplicate warnings
std::set warned_;
- // whether the given project name is a gamebryo task, `dir` is just for
- // logging
- //
- bool is_gamebryo_plugin(const std::string& dir, const std::string& project);
-
// parses the directory name, walks all the .ts files, returns a project
// object for them
//
@@ -637,7 +209,7 @@ namespace mob::tasks {
// returns a lang object that contains at least the given main_ts_file,
// but might contain more if it's a gamebryo plugin
//
- lang create_lang(bool gamebryo, const std::string& project_name,
+ lang create_lang(const std::string& project_name,
const fs::path& main_ts_file);
};
@@ -677,22 +249,4 @@ namespace mob::tasks {
config = config::release) const;
};
- class zlib : public basic_task {
- public:
- zlib();
-
- static std::string version();
- static bool prebuilt();
- static fs::path source_path();
-
- protected:
- void do_clean(clean c) override;
- void do_fetch() override;
- void do_build_and_install() override;
-
- private:
- cmake create_cmake_tool(cmake::ops o = cmake::generate);
- msbuild create_msbuild_tool(msbuild::ops o = msbuild::build);
- };
-
} // namespace mob::tasks
diff --git a/src/tasks/translations.cpp b/src/tasks/translations.cpp
index bc29c50..6910b19 100644
--- a/src/tasks/translations.cpp
+++ b/src/tasks/translations.cpp
@@ -125,9 +125,6 @@ namespace mob::tasks {
// walks all the .ts files in the project, creates a `lang` object for
// each
//
- // each project directory is named "mod-organizer-2.project_name", so this
- // splits on the dot to get the project name, checks if it's a gamebryo
- // plugin, and adds the gamebryo .ts file as well if necessary
// splitting
const auto dir_name = path_to_utf8(dir.filename());
@@ -150,7 +147,6 @@ namespace mob::tasks {
// project
project p(project_name);
- const bool gamebryo = is_gamebryo_plugin(dir_name, project_name);
// for each file
for (auto f : fs::directory_iterator(dir)) {
@@ -168,14 +164,14 @@ namespace mob::tasks {
}
// add a new `lang` object for it
- p.langs.push_back(create_lang(gamebryo, project_name, f.path()));
+ p.langs.push_back(create_lang(project_name, f.path()));
}
return p;
}
translations::projects::lang
- translations::projects::create_lang(bool gamebryo, const std::string& project_name,
+ translations::projects::create_lang(const std::string& project_name,
const fs::path& main_ts_file)
{
lang lg(path_to_utf8(main_ts_file.stem()));
@@ -183,64 +179,9 @@ namespace mob::tasks {
// every lang has the .ts file from the project, gamebryo plugins have more
lg.ts_files.push_back(main_ts_file);
- if (gamebryo) {
- // this is a gamebryo plugin, so it needs the gamebryo .ts file as well,
- // find it
-
- // the .ts files for gamebryo are in mod-organizer-2.game_gamebryo/
- const fs::path gamebryo_dir =
- conf().transifex().get("project") + "." + "game_gamebryo";
-
- // the .ts file has the same name, it's just "lang.ts"
- const auto gamebryo_ts = root_ / gamebryo_dir / main_ts_file.filename();
-
- if (fs::exists(gamebryo_ts)) {
- // found, add it
- lg.ts_files.push_back(gamebryo_ts);
- }
- else {
- // not found, that means the plugin was translated into a language,
- // but the gamebryo project wasn't; warn once
- if (!warned_.contains(gamebryo_ts)) {
- warned_.insert(gamebryo_ts);
-
- warnings_.push_back(::std::format(
- "{} is a gamebryo plugin but there is no '{}'; the "
- ".qm file will be missing some translations (will "
- "only warn once)",
- project_name, path_to_utf8(gamebryo_ts)));
- }
- }
- }
-
return lg;
}
- bool translations::projects::is_gamebryo_plugin(const std::string& dir,
- const std::string& project)
- {
- const auto* t = task_manager::instance().find_one(project);
-
- if (!t) {
- warnings_.push_back(
- ::std::format("directory '{}' was parsed as project '{}', but there's "
- "no task with this name",
- dir, project));
-
- return false;
- }
-
- // gamebryo plugins are all `modorganizer` tasks
- const auto* mo_task = static_cast(t);
- if (!mo_task) {
- // not an mo task, can't be a gamebryo plugin
- return false;
- }
-
- // check the flag
- return mo_task->is_gamebryo_plugin();
- }
-
translations::translations() : task("translations") {}
fs::path translations::source_path()
diff --git a/src/tasks/usvfs.cpp b/src/tasks/usvfs.cpp
index e2bfe3d..2c3e7e9 100644
--- a/src/tasks/usvfs.cpp
+++ b/src/tasks/usvfs.cpp
@@ -76,8 +76,10 @@ namespace mob::tasks {
{
run_tool(create_cmake_tool(arch::x64));
run_tool(create_cmake_tool(arch::x86));
- run_tool(create_msbuild_tool(arch::x64));
- run_tool(create_msbuild_tool(arch::x86));
+ run_tool(create_msbuild_tool(arch::x64, msbuild::build,
+ task_conf().configuration()));
+ run_tool(create_msbuild_tool(arch::x86, msbuild::build,
+ task_conf().configuration()));
}
cmake usvfs::create_cmake_tool(arch a, cmake::ops o) const
diff --git a/src/tasks/zlib.cpp b/src/tasks/zlib.cpp
deleted file mode 100644
index 1eeb8e4..0000000
--- a/src/tasks/zlib.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "pch.h"
-#include "tasks.h"
-
-namespace mob::tasks {
-
- zlib::zlib() : basic_task("zlib") {}
-
- std::string zlib::version()
- {
- return conf().version().get("zlib");
- }
-
- bool zlib::prebuilt()
- {
- return false;
- }
-
- fs::path zlib::source_path()
- {
- return conf().path().build() / ("zlib-" + version());
- }
-
- void zlib::do_clean(clean c)
- {
- // delete the whole directory
- if (is_set(c, clean::reclone)) {
- git_wrap::delete_directory(cx(), source_path());
-
- // no point in doing anything more
- return;
- }
-
- // cmake clean
- if (is_set(c, clean::reconfigure))
- run_tool(create_cmake_tool(cmake::clean));
-
- // msbuild clean
- if (is_set(c, clean::rebuild))
- run_tool(create_msbuild_tool(msbuild::clean));
- }
-
- void zlib::do_fetch()
- {
- run_tool(make_git()
- .url(make_git_url("madler", "zlib"))
- .branch(version())
- .root(source_path()));
- }
-
- void zlib::do_build_and_install()
- {
- const fs::path build_path = run_tool(create_cmake_tool());
-
- run_tool(create_msbuild_tool());
-
- // zconf.h needs to be copied to the root directory, it's where python
- // looks for it
- op::copy_file_to_dir_if_better(cx(), build_path / "zconf.h", source_path());
- }
-
- cmake zlib::create_cmake_tool(cmake::ops o)
- {
- return std::move(cmake(o)
- .generator(cmake::vs)
- .root(source_path())
- .arg("-Wno-deprecated")
- .prefix(source_path()));
- }
-
- msbuild zlib::create_msbuild_tool(msbuild::ops o)
- {
- const fs::path build_path = create_cmake_tool().build_path();
- return std::move(msbuild(o).solution(build_path / "INSTALL.vcxproj"));
- }
-
-} // namespace mob::tasks
diff --git a/src/tools/cmake.cpp b/src/tools/cmake.cpp
index 3d8e629..3a89ff2 100644
--- a/src/tools/cmake.cpp
+++ b/src/tools/cmake.cpp
@@ -114,6 +114,12 @@ namespace mob {
return *this;
}
+ cmake& cmake::configuration_types(const std::vector& configs)
+ {
+ config_types_ = configs;
+ return *this;
+ }
+
cmake& cmake::cmd(const std::string& s)
{
cmd_ = s;
@@ -181,6 +187,16 @@ namespace mob {
p = p.arg("--preset").arg(preset_);
}
+ if (!config_types_.empty()) {
+ std::string types;
+ for (const auto& c : config_types_) {
+ if (!types.empty())
+ types += ";";
+ types += config_to_string(c);
+ }
+ p = p.arg("-DCMAKE_CONFIGURATION_TYPES=" + types);
+ }
+
p = p.arg("-DCMAKE_INSTALL_MESSAGE=" +
conf_cmake::to_string(conf().cmake().install_message()))
.arg("--log-level=ERROR")
diff --git a/src/tools/cmake.h b/src/tools/cmake.h
index 9420fc5..11a289a 100644
--- a/src/tools/cmake.h
+++ b/src/tools/cmake.h
@@ -69,6 +69,9 @@ namespace mob {
//
cmake& configuration(mob::config config);
+ // set the configuration types available when generating
+ cmake& configuration_types(const std::vector& configs);
+
// overrides the directory in which cmake will write build files
//
// by default, this is a directory inside what was given in root() with a
@@ -184,6 +187,9 @@ namespace mob {
// configuration
mob::config config_{mob::config::relwithdebinfo};
+ // configuration types
+ std::vector config_types_;
+
// passed verbatim
std::vector args_;
diff --git a/src/tools/jom.cpp b/src/tools/jom.cpp
deleted file mode 100644
index 66e6bc8..0000000
--- a/src/tools/jom.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "pch.h"
-#include "../core/conf.h"
-#include "../core/process.h"
-#include "tools.h"
-
-namespace mob {
-
- jom::jom() : basic_process_runner("jom"), arch_(arch::def) {}
-
- fs::path jom::binary()
- {
- return conf().tool().get("jom");
- }
-
- jom& jom::path(const fs::path& p)
- {
- cwd_ = p;
- return *this;
- }
-
- jom& jom::target(const std::string& s)
- {
- target_ = s;
- return *this;
- }
-
- jom& jom::def(const std::string& s)
- {
- def_.push_back(s);
- return *this;
- }
-
- jom& jom::flag(flags_t f)
- {
- flags_ = f;
- return *this;
- }
-
- jom& jom::architecture(arch a)
- {
- arch_ = a;
- return *this;
- }
-
- int jom::result() const
- {
- return exit_code();
- }
-
- void jom::do_run()
- {
- process p;
-
- // jom doesn't handle sigint well, it just continues, so kill it on
- // interruption
- auto pflags = process::terminate_on_interrupt;
-
- if (flags_ & allow_failure) {
- // tasks will set allow_failure for the first couple of runs of jom,
- // which often fails because of the /J multi-process flag, so don't log
- // errors in that case
- p.stderr_level(context::level::trace);
- pflags |= process::allow_failure;
- }
-
- p.binary(binary())
- .cwd(cwd_)
- .stderr_filter([](process::filter& f) {
- // initial log line, can't get rid of it, /L or /NOLOGO don't seem
- // to work
- if (f.line.find("empower your cores") != std::string::npos)
- f.lv = context::level::trace;
- })
- .arg("/C", process::log_quiet) // silent
- .arg("/S", process::log_quiet) // silent
- .arg("/L", process::log_quiet) // silent, jom likes to spew crap
- .arg("/D", process::log_dump) // verbose stuff
- .arg("/P", process::log_dump) // verbose stuff
- .arg("/W", process::log_dump) // verbose stuff
- .arg("/K"); // don't stop on errors
-
- if (flags_ & single_job)
- p.arg("/J", "1"); // single-process
-
- for (auto&& def : def_)
- p.arg(def);
-
- p.arg(target_).flags(pflags).env(env::vs(arch_));
-
- execute_and_join(p);
- }
-
-} // namespace mob
diff --git a/src/tools/nmake.cpp b/src/tools/nmake.cpp
deleted file mode 100644
index abd011e..0000000
--- a/src/tools/nmake.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "pch.h"
-#include "../core/conf.h"
-#include "../core/process.h"
-#include "tools.h"
-
-namespace mob {
-
- nmake::nmake() : basic_process_runner("nmake"), arch_(arch::def) {}
-
- fs::path nmake::binary()
- {
- return conf().tool().get("nmake");
- }
-
- nmake& nmake::path(const fs::path& p)
- {
- cwd_ = p;
- return *this;
- }
-
- nmake& nmake::target(const std::string& s)
- {
- target_ = s;
- return *this;
- }
-
- nmake& nmake::def(const std::string& s)
- {
- def_.push_back(s);
- return *this;
- }
-
- nmake& nmake::architecture(arch a)
- {
- arch_ = a;
- return *this;
- }
-
- int nmake::result() const
- {
- return exit_code();
- }
-
- void nmake::do_run()
- {
- process p;
-
- p.binary(binary())
- .cwd(cwd_)
- .stderr_filter([](process::filter& f) {
- // initial log line, can't get rid of it, /L or /NOLOGO don't seem
- // to work
- if (f.line.find("Microsoft (R) Macro Assembler (x64)") !=
- std::string::npos)
- f.lv = context::level::trace;
- if (f.line.find("Copyright (C) Microsoft Corporation.") !=
- std::string::npos)
- f.lv = context::level::trace;
- if (f.line.find("Microsoft (R) Program Maintenance Utility") !=
- std::string::npos)
- f.lv = context::level::trace;
- })
- .arg("/C", process::log_quiet) // silent
- .arg("/S", process::log_quiet) // silent
- .arg("/L", process::log_quiet) // silent, nmake likes to spew crap
- .arg("/D", process::log_dump) // verbose stuff
- .arg("/P", process::log_dump) // verbose stuff
- .arg("/W", process::log_dump) // verbose stuff
- .arg("/K"); // don't stop on errors
-
- for (auto&& def : def_)
- p.arg(def);
-
- p.arg(target_).env(env::vs(arch_));
-
- execute_and_join(p);
- }
-
-} // namespace mob
diff --git a/src/tools/patcher.cpp b/src/tools/patcher.cpp
deleted file mode 100644
index 7966297..0000000
--- a/src/tools/patcher.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "pch.h"
-#include "../core/conf.h"
-#include "../core/process.h"
-#include "tools.h"
-
-namespace mob {
-
- patcher::patcher() : basic_process_runner("patch"), prebuilt_(false) {}
-
- fs::path patcher::binary()
- {
- return conf().tool().get("patch");
- }
-
- patcher& patcher::task(const std::string& name, bool prebuilt)
- {
- task_ = name;
- prebuilt_ = prebuilt;
- return *this;
- }
-
- patcher& patcher::file(const fs::path& p)
- {
- file_ = p;
- return *this;
- }
-
- patcher& patcher::root(const fs::path& dir)
- {
- root_ = dir;
- return *this;
- }
-
- void patcher::do_run()
- {
- // patches should be in mob/patches/task-name, but not all tasks need
- // patches
- const fs::path root = conf().path().patches() / task_;
-
- if (!fs::exists(root)) {
- cx().trace(context::generic,
- "patch directory {} doesn't exist, assuming no patches", root);
-
- return;
- }
-
- if (!file_.empty()) {
- // patcher tool is being run for a manual patch
- cx().trace(context::generic, "doing manual patch from {}", file_);
- do_patch(root / file_);
- return;
- }
-
- // patcher tool is being by the task for auto patching, figure out the
- // directory to use depending on whether it's a prebuilt
- const fs::path patches = root / (prebuilt_ ? "prebuilt" : "sources");
- cx().trace(context::generic, "looking for patches in {}", patches);
-
- if (!fs::exists(patches)) {
- cx().trace(context::generic,
- "patch directory {} doesn't exist, assuming no patches",
- patches);
-
- return;
- }
-
- // for each path file
- for (auto e : fs::directory_iterator(patches)) {
- if (!e.is_regular_file()) {
- cx().trace(context::generic, "skipping {}, not a file", e.path());
- continue;
- }
-
- const auto p = e.path();
-
- if (p.extension() == ".manual_patch") {
- cx().trace(context::generic, "skipping manual patch {}", e.path());
- continue;
- }
- else if (p.extension() != ".patch") {
- cx().warning(context::generic, "file with unknown extension {}", p);
- continue;
- }
-
- do_patch(p);
- }
- }
-
- void patcher::do_patch(const fs::path& patch)
- {
- // there's no way to figure out if patch failure is because 1) the patch
- // file is incorrect, or 2) the patch has already been applied
- //
- // an incorrect patch file would probably mean that the source has changed
- // and the patch must be updated or removed if it's not required anymore
- //
- // so patching is a two step process: check if the patch has already been
- // applied, and apply it if it hasn't
-
- // use by both the check and apply processes
- const auto base = process()
- .binary(binary())
- .arg("--read-only", "ignore")
- .arg("--strip", "0")
- .arg("--directory", root_)
- .arg("--quiet", process::log_quiet);
-
- // process to reverse the path: the only way to check if a patch has been
- // applied is actually to try to reverse it and check if there was an error
- //
- // this uses --dry-run because if the file was already patched, it shouldn't
- // actually be reversed
- auto check = process(base)
- .flags(process::allow_failure)
- .arg("--dry-run")
- .arg("--force") // no prompts
- .arg("--reverse") // swaps old and new files
- .arg("--input", patch);
-
- // process to apply the patch
- auto apply =
- process(base)
- .arg("--forward") // don't try to reverse the patch if it fails
- .arg("--batch") // no prompts
- .arg("--input", patch);
-
- cx().trace(context::generic, "trying to patch using {}", patch);
-
- {
- // check, returns 0 when the patch would have been reversed correctly,
- // 1 if not, anything else on error
- cx().trace(context::generic, "checking if already patched");
- const auto ret = execute_and_join(check);
-
- if (ret == 0) {
- // reversing the patch would succeed, so the patch has already been
- // applied
- cx().trace(context::generic, "patch {} already applied", patch);
- return;
- }
-
- // anything other than 0 or 1 is a hard error
- if (ret != 1)
- cx().bail_out(context::generic, "patch returned {}", ret);
-
- cx().trace(context::generic, "looks like the patch is needed");
- }
-
- {
- // apply
- cx().trace(context::generic, "applying patch {}", patch);
- execute_and_join(apply);
- }
- }
-
-} // namespace mob
diff --git a/src/tools/python.cpp b/src/tools/python.cpp
deleted file mode 100644
index 46c79bc..0000000
--- a/src/tools/python.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-#include "pch.h"
-#include "../core/process.h"
-#include "../tasks/tasks.h"
-#include "tools.h"
-
-namespace mob {
-
- python::python() : basic_process_runner("python") {}
-
- python& python::root(const fs::path& p)
- {
- root_ = p;
- return *this;
- }
-
- python& python::arg(const std::string& s)
- {
- args_.push_back(s);
- return *this;
- }
-
- void python::do_run()
- {
- // python is a bit finicky for utf8, so:
- // 1) chcp changes the codepage to utf8
- // 2) `-X utf8` and the PYTHONUTF8 environment variable are set, which
- // is probably redundant
-
- auto p = process()
- .binary(tasks::python::python_exe())
- .chcp(65001)
- .stdout_encoding(encodings::utf8)
- .stderr_encoding(encodings::utf8)
- .stderr_filter([&](process::filter& f) {
- // filter out crap from setuptools
- if (f.line.find("zip_safe flag not set") != std::string::npos)
- f.lv = context::level::trace;
- else if (f.line.find("module references __file__") !=
- std::string::npos)
- f.lv = context::level::trace;
- })
- .arg("-X", "utf8"); // forces utf8
-
- for (auto&& a : args_)
- p.arg(a);
-
- p.cwd(root_).env(this_env::get().set("PYTHONUTF8", "1")); // forces utf8
-
- execute_and_join(p);
- }
-
- pip::pip(ops op) : basic_process_runner("pip"), op_(op), no_deps_{false} {}
-
- pip& pip::package(const std::string& s)
- {
- package_ = s;
- return *this;
- }
-
- pip& pip::version(const std::string& s)
- {
- version_ = s;
- return *this;
- }
-
- pip& pip::file(const fs::path& p)
- {
- file_ = p;
- return *this;
- }
-
- pip& pip::no_dependencies()
- {
- no_deps_ = true;
- return *this;
- }
-
- void pip::do_run()
- {
- switch (op_) {
- case ensure:
- do_ensure();
- break;
-
- case install:
- do_install();
- break;
-
- case download:
- do_download();
- break;
-
- default:
- cx().bail_out(context::generic, "pip unknown op {}", op_);
- }
- }
-
- void pip::do_ensure()
- {
- // ensure
- execute_and_join(
- process()
- .stderr_filter([](auto&& f) {
- // this spits out two warnings about not being on PATH and suggests
- // to add --no-warn-script-location, but that's not actually a valid
- // parameter for `ensurepip` and it fails, unlike the `install`
- // commands below
- //
- // so just filter it out
-
- if (f.line.find("which is not on PATH") != std::string::npos)
- f.lv = context::level::debug;
- else if (f.line.find("Consider adding this") != std::string::npos)
- f.lv = context::level::debug;
- })
- .binary(tasks::python::python_exe())
- .arg("-m", "ensurepip"));
-
- // upgrade
- execute_and_join(process()
- .binary(tasks::python::python_exe())
- .arg("-m pip")
- .arg("install")
- .arg("--no-warn-script-location")
- .arg("--upgrade pip"));
-
- // ssl errors while downloading through python without certifi
- execute_and_join(process()
- .binary(tasks::python::python_exe())
- .arg("-m pip")
- .arg("install")
- .arg("--no-warn-script-location")
- .arg("certifi"));
- }
-
- void pip::do_install()
- {
- auto p = process()
- .binary(tasks::python::python_exe())
- .chcp(65001)
- .stdout_encoding(encodings::utf8)
- .stderr_encoding(encodings::utf8)
- .arg("-X", "utf8")
- .arg("-m", "pip")
- .arg("install")
- .arg("--force")
- .arg("--no-warn-script-location")
- .arg("--disable-pip-version-check");
-
- if (!package_.empty()) {
- if (version_.empty()) {
- p.arg(package_);
- }
- else {
- p.arg(package_ + "==" + version_);
- }
- }
- else if (!file_.empty())
- p.arg(file_);
-
- if (no_deps_) {
- p.arg("--no-dependencies");
- }
-
- p.env(this_env::get().set("PYTHONUTF8", "1"));
-
- execute_and_join(p);
- }
-
- void pip::do_download()
- {
- execute_and_join(process()
- .binary(tasks::python::python_exe())
- .chcp(65001)
- .stdout_encoding(encodings::utf8)
- .stderr_encoding(encodings::utf8)
- .arg("-X", "utf8")
- .arg("-m", "pip")
- .arg("download")
- .arg("--no-binary=:all:")
- .arg("--no-deps")
- .arg("-d", conf().path().cache())
- .arg(package_ + "==" + version_)
- .env(this_env::get().set("PYTHONUTF8", "1")));
- }
-
-} // namespace mob
diff --git a/src/tools/tools.cpp b/src/tools/tools.cpp
index 28549d0..a0779fe 100644
--- a/src/tools/tools.cpp
+++ b/src/tools/tools.cpp
@@ -73,16 +73,6 @@ namespace mob {
return gcx();
}
- fs::path perl::binary()
- {
- return conf().tool().get("perl");
- }
-
- fs::path nasm::binary()
- {
- return conf().tool().get("nasm");
- }
-
fs::path qt::installation_path()
{
return conf().path().qt_install();
@@ -201,19 +191,6 @@ namespace mob {
return trim_copy(p.stdout_string());
}
- nuget::nuget(fs::path sln) : basic_process_runner("nuget"), sln_(std::move(sln)) {}
-
- fs::path nuget::binary()
- {
- return conf().tool().get("nuget");
- }
-
- void nuget::do_run()
- {
- execute_and_join(process().binary(binary()).arg("restore").arg(sln_).cwd(
- sln_.parent_path()));
- }
-
transifex::transifex(ops o)
: basic_process_runner("transifex"), op_(o), stdout_(context::level::trace),
min_(100), force_(false)
diff --git a/src/tools/tools.h b/src/tools/tools.h
index 3d16fef..47d85eb 100644
--- a/src/tools/tools.h
+++ b/src/tools/tools.h
@@ -95,23 +95,6 @@ namespace mob {
// these are not strictly tools, but they're a centralized place for perl,
// nasm, qt and vswhere stuff
- // only used when building openssl from source
- //
- struct perl {
- // path to perl binary
- //
- static fs::path binary();
- };
-
- // only used when building openssl from source, bundled with mob in
- // third-party/bin
- //
- struct nasm {
- // path to nasm binary
- //
- static fs::path binary();
- };
-
struct qt {
// path to qt's root directory, the one that contains bin, include, etc.
//
@@ -365,199 +348,6 @@ namespace mob {
const fs::path& files_root);
};
- // tool to apply patches available for a third-party task; patches live in
- // mob/patches, in one directory per task
- //
- // patch.exe is bundled with mob in third-party/bin
- //
- // there are two ways of patching a task:
- //
- // 1) auto patching: each task runs the patcher tool as a step in
- // task::fetch(), just after calling do_fetch(), which checks for a
- // directory `patches/task-name/sources` or `patches/task-name/prebuilt`
- // depending on whether this is a prebuilt or not
- //
- // any file ending with `.patch` will be applied, rooted in the path
- // given to root() (defaults to the task's source directory)
- //
- // 2) manual patching: a task can run the patcher with a specific patch file
- // given in file() at any time, which is useful for tasks that need to
- // patch files generated later in the building process, such as pyqt
- //
- // manual patch files can be anywhere, but they're in patches/task-name with
- // a `.manual_patch` by convention
- //
- class patcher : public basic_process_runner {
- public:
- // path to the patch binary
- //
- static fs::path binary();
-
- patcher();
-
- // sets the task name and whether it's a prebuilt, used in task::fetch() for
- // auto patching
- //
- patcher& task(const std::string& name, bool prebuilt = false);
-
- // sets the patch's filename; if this is not set, uses the task name and
- // prebuilt flag from task()
- //
- patcher& file(const fs::path& p);
-
- // directory in which the patches are applied; the filenames in the patch
- // files must be relative to this directory
- //
- patcher& root(const fs::path& dir);
-
- protected:
- // applies the patch file from the task directory or the patch file given
- // in file()
- //
- void do_run() override;
-
- private:
- // task name and prebuilt flag, used to generate the auto patching directory
- std::string task_;
- bool prebuilt_;
-
- // root directory, used to resolve the relative file names in the patch
- // files
- fs::path root_;
-
- // patch file, empty for auto patching
- fs::path file_;
-
- // applies one patch file
- //
- void do_patch(const fs::path& patch_file);
- };
-
- // tool that runs `nmake`
- //
- class nmake : public basic_process_runner {
- public:
- // path to the job binary
- //
- static fs::path binary();
-
- nmake();
-
- // path in which to invoke nmake
- //
- nmake& path(const fs::path& p);
-
- // makefile target
- //
- nmake& target(const std::string& s);
-
- // adds a macro definition as "NAME=value"
- //
- nmake& def(const std::string& s);
-
- // sets the architecture used to run nmake, used to get the appropriate
- // VS environment variables, defaults to arch::def
- //
- nmake& architecture(arch a);
-
- // nmake's exit code
- //
- int result() const;
-
- protected:
- // runs nmake
- //
- void do_run() override;
-
- private:
- // set in path()
- fs::path cwd_;
-
- // set in def(), just plain arguments
- std::vector def_;
-
- // set in target(), another plain argument
- std::string target_;
-
- // set in architecture()
- arch arch_;
- };
-
- // tool that runs `jom`, an alternative to `nmake` that supports parallel
- // builds, bundled with mob in third-party/bin
- //
- // note that although jom reduces build times considerably, some third parties
- // don't handle it very well, giving a bunch of errors about files in use, etc.
- //
- // so most tools that use jom use a loop that runs jom several times, allowing
- // failure, and then run jom one last time in single_job mode to finish the
- // build, which should be guaranteed to work
- //
- class jom : public basic_process_runner {
- public:
- // path to the job binary
- //
- static fs::path binary();
-
- enum flags_t {
- noflags = 0x00,
-
- // disables multi-process build
- single_job = 0x01,
-
- // don't bail out on failure
- allow_failure = 0x02
- };
-
- jom();
-
- // path in which to invoke jom
- //
- jom& path(const fs::path& p);
-
- // makefile target
- //
- jom& target(const std::string& s);
-
- // adds a macro definition as "NAME=value"
- //
- jom& def(const std::string& s);
-
- // sets flags
- //
- jom& flag(flags_t f);
-
- // sets the architecture used to run jom, used to get the appropriate
- // VS environment variables, defaults to arch::def
- //
- jom& architecture(arch a);
-
- // jom's exit code
- //
- int result() const;
-
- protected:
- // runs jom
- //
- void do_run() override;
-
- private:
- // set in path()
- fs::path cwd_;
-
- // set in def(), just plain arguments
- std::vector def_;
-
- // set in target(), another plain argument
- std::string target_;
-
- // set in flag()
- flags_t flags_;
-
- // set in architecture()
- arch arch_;
- };
-
// tool that runs devenv.exe, only invoked to upgrade projects for now
//
class vs : public basic_process_runner {
@@ -619,125 +409,6 @@ namespace mob {
void do_upgrade();
};
- // tool that runs `nuget restore` for the given solution, bundled with mob in
- // third-party/bin
- //
- class nuget : public basic_process_runner {
- public:
- // nuget tool for the given solution
- //
- nuget(fs::path sln);
-
- // path to the nuget binary
- //
- static fs::path binary();
-
- protected:
- // runs nuget
- void do_run() override;
-
- private:
- // solution file set in constructor
- fs::path sln_;
- };
-
- // tool that runs python
- //
- class python : public basic_process_runner {
- public:
- python();
-
- // working directory
- //
- python& root(const fs::path& p);
-
- // arbitrary arguments given to python
- //
- python& arg(const std::string& s);
-
- protected:
- // runs python
- //
- void do_run() override;
-
- private:
- // working directory
- fs::path root_;
-
- // arguments
- std::vector args_;
- };
-
- // tool that runs pip for one of the operations in the enum
- //
- class pip : public basic_process_runner {
- public:
- // what run() should do
- //
- enum ops {
- // installs pip if needed and updates it
- ensure = 1,
-
- // runs `-m pip install` for the given package/version or file
- //
- install,
-
- // runs `-m pip download` for the given package and version, does not
- // use file()
- download
- };
-
- // a pip tool for the given operation
- //
- pip(ops o);
-
- // `pip install` can work with either a "package==version" string, which
- // downloads the file if needed, or a local file
- //
- // so for the `install` operation, either package/version or file can be
- // given, but the `download` operation requires the package/version only
- // and puts the downloaded file in the "cache" path (defaults to the
- // downloads/ directory)
- //
- pip& package(const std::string& s);
- pip& version(const std::string& s);
- pip& file(const fs::path& p);
-
- // do not install dependencies for the package
- //
- pip& no_dependencies();
-
- protected:
- // runs pip
- //
- void do_run() override;
-
- private:
- // what pip command to run
- ops op_;
-
- // set in package(), version() and file()
- std::string package_;
- std::string version_;
- fs::path file_;
-
- // no depndencies
- bool no_deps_;
-
- // runs `-m ensurepip`, then upgrades pip
- //
- void do_ensure();
-
- // runs `-m pip install` with the given package/version or file
- //
- void do_install();
-
- // runs `-m pip download` with the given package/version, saves the file
- // in the cache directory
- //
- void do_download();
- };
-
// tool that runs transifex, used for pulling translations before release,
// bundled with mob in third-party/bin
//
diff --git a/src/utility.h b/src/utility.h
index a0becf4..3b833e3 100644
--- a/src/utility.h
+++ b/src/utility.h
@@ -50,16 +50,6 @@ namespace mob {
class url;
- // returns a url for a prebuilt binary having the given filename; prebuilts are
- // hosted on github, in the umbrella repo
- //
- url make_prebuilt_url(const std::string& filename);
-
- // returns a url for an appveyor artifact; this is used by usvfs for prebuilts
- //
- url make_appveyor_artifact_url(arch a, const std::string& project,
- const std::string& filename);
-
// returns "mob x.y"
//
std::string mob_version();