mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
* Build components in all variant for boost to avoid issue with USVFS. * Build googletest in both Debug and Release. * Allow build configurations other than RelWithDebInfo.
277 lines
7.2 KiB
C++
277 lines
7.2 KiB
C++
#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<bool>("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
|