Files
mob/src/tasks/python.cpp
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

277 lines
7.2 KiB
C++
Raw Normal View History

2020-04-29 22:10:55 -04:00
#include "pch.h"
#include "../core/process.h"
2020-04-29 22:10:55 -04:00
#include "tasks.h"
2020-12-02 10:52:37 -05:00
// see the top of pyqt.cpp for some stuff about python/sip/pyqt
2020-11-18 00:42:43 -05:00
namespace mob::tasks {
2020-04-29 22:10:55 -04:00
2020-12-02 10:52:37 -05:00
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");
2020-12-02 10:52:37 -05:00
}
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
2020-04-29 22:10:55 -04:00
python::python() : basic_task("python") {}
2020-12-02 10:52:37 -05:00
2020-04-29 22:10:55 -04:00
std::string python::version()
2023-09-19 18:28:24 +02:00
{
2020-04-29 22:10:55 -04:00
return conf().version().get("python");
}
2020-05-17 14:14:29 -04:00
bool python::prebuilt()
2020-05-07 11:08:33 -04:00
{
2020-11-21 00:39:41 -05:00
return conf().prebuilt().get<bool>("python");
2020-05-07 11:08:33 -04:00
}
python::version_info python::parsed_version()
{
// v3.8.1
2020-11-22 10:08:26 -05:00
// v and .1 are optional
std::regex re(R"(v?(\d+)\.(\d+)(?:\.(\d+))?)");
2020-04-29 22:10:55 -04:00
std::smatch m;
2020-05-07 11:08:33 -04:00
const auto s = version();
2020-04-29 22:10:55 -04:00
2020-05-17 14:14:29 -04:00
if (!std::regex_match(s, m, re))
gcx().bail_out(context::generic, "bad python version '{}'", s);
2020-11-20 21:15:05 -05:00
version_info v;
2020-04-29 22:10:55 -04:00
v.major = m[1];
v.minor = m[2];
2020-05-13 13:32:52 -04:00
v.patch = m[3];
2020-04-29 22:10:55 -04:00
return v;
2023-09-19 18:28:24 +02:00
}
2020-04-29 22:10:55 -04:00
2020-05-07 14:06:37 -04:00
fs::path python::source_path()
2023-09-19 18:28:24 +02:00
{
2020-04-29 22:10:55 -04:00
return conf().path().build() / ("python-" + version_without_v());
}
2020-05-07 14:06:37 -04:00
fs::path python::build_path()
{
2020-11-21 00:39:41 -05:00
return source_path() / "PCBuild" / "amd64";
2020-04-29 22:10:55 -04:00
}
config python::build_type()
{
return conf().build_types().get("python");
}
2020-05-02 04:03:20 -04:00
void python::do_clean(clean c)
2023-09-19 18:28:24 +02:00
{
2020-05-02 04:03:20 -04:00
if (prebuilt()) {
// delete download
if (is_set(c, clean::redownload))
run_tool(downloader(prebuilt_url(), downloader::clean));
2020-05-25 00:31:49 -04:00
// delete the whole directory
if (is_set(c, clean::reextract)) {
2020-11-27 05:59:02 -05:00
cx().trace(context::reextract, "deleting {}", source_path());
op::delete_directory(cx(), source_path(), op::optional);
2023-09-19 18:28:24 +02:00
}
}
2020-05-20 05:41:19 -04:00
else {
2020-12-02 10:52:37 -05:00
// delete the whole directory
2020-11-27 05:59:02 -05:00
if (is_set(c, clean::reclone)) {
git_wrap::delete_directory(cx(), source_path());
2020-05-25 01:43:16 -04:00
2020-12-02 10:52:37 -05:00
// no need to do anything else
2020-11-27 05:59:02 -05:00
return;
}
2020-12-02 10:52:37 -05:00
// msbuild clean
if (is_set(c, clean::rebuild))
2020-11-27 05:59:02 -05:00
run_tool(create_msbuild_tool(msbuild::clean));
}
2023-09-19 18:28:24 +02:00
}
2020-11-27 05:59:02 -05:00
void python::do_fetch()
2023-09-19 18:28:24 +02:00
{
2020-11-27 05:59:02 -05:00
if (prebuilt())
fetch_prebuilt();
2023-09-19 18:28:24 +02:00
else
2020-05-07 14:06:37 -04:00
fetch_from_source();
2020-05-04 08:37:17 -04:00
}
2020-04-29 22:10:55 -04:00
void python::do_build_and_install()
2020-05-07 14:06:37 -04:00
{
if (prebuilt())
build_and_install_prebuilt();
else
build_and_install_from_source();
}
void python::fetch_prebuilt()
{
const auto file = run_tool(downloader(prebuilt_url()));
2020-11-27 05:59:02 -05:00
run_tool(extractor().file(file).output(source_path()));
2023-09-19 18:28:24 +02:00
}
2020-05-07 14:06:37 -04:00
2020-11-27 05:59:02 -05:00
void python::build_and_install_prebuilt()
2023-09-19 18:28:24 +02:00
{
2020-11-27 05:59:02 -05:00
install_pip();
copy_files();
2020-05-07 14:06:37 -04:00
}
void python::fetch_from_source()
{
run_tool(make_git()
.url(make_git_url("python", "cpython"))
2020-11-27 05:59:02 -05:00
.branch(version())
.root(source_path()));
2020-05-07 14:06:37 -04:00
}
void python::build_and_install_from_source()
2020-04-29 22:10:55 -04:00
{
2024-05-25 14:25:40 +02:00
// download externals
prepare_dependencies();
2023-09-19 18:28:24 +02:00
// build
run_tool(create_msbuild_tool());
2020-04-29 22:10:55 -04:00
2020-05-07 14:06:37 -04:00
// package stuff into pythoncore.zip
2020-11-27 05:59:02 -05:00
package();
2020-12-02 10:52:37 -05:00
// install pip for other tasks that need it
2020-11-27 05:59:02 -05:00
install_pip();
2020-05-07 14:06:37 -04:00
2020-12-02 10:52:37 -05:00
// boost.python expects pyconfig.h to be in the include path
op::copy_file_to_dir_if_better(cx(), source_path() / "PC" / "pyconfig.h",
2020-11-27 05:59:02 -05:00
include_path());
2020-05-07 14:06:37 -04:00
2020-11-27 05:59:02 -05:00
copy_files();
2023-09-19 18:28:24 +02:00
}
2020-05-20 05:41:19 -04:00
2024-05-25 14:25:40 +02:00
void python::prepare_dependencies()
{
const auto bat = source_path() / "PCBuild" / "get_externals.bat";
run_tool(process_runner(process().binary(bat).cwd(source_path())));
}
2020-05-04 08:37:17 -04:00
void python::package()
2023-09-19 18:28:24 +02:00
{
2020-11-27 05:59:02 -05:00
if (fs::exists(python_core_zip_file())) {
cx().trace(context::bypass, "python already packaged");
2023-09-19 18:28:24 +02:00
return;
2020-05-04 08:37:17 -04:00
}
const auto bat = source_path() / "python.bat";
2020-04-29 22:10:55 -04:00
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");
}
2020-12-02 10:52:37 -05:00
// package libs into pythonXX.zip
run_tool(process_runner(p));
2023-09-19 18:28:24 +02:00
}
2020-04-29 22:10:55 -04:00
2020-12-02 10:52:37 -05:00
void python::copy_files()
2023-09-19 18:28:24 +02:00
{
2020-12-02 10:52:37 -05:00
// libs
op::copy_glob_to_dir_if_better(cx(), build_path() / "*.lib",
conf().path().install_libs(), op::copy_files);
2020-04-29 22:10:55 -04:00
2020-12-02 10:52:37 -05:00
// pdbs
2020-05-06 05:22:42 -04:00
op::copy_file_to_dir_if_better(
cx(),
build_path() / ("python" + version_for_dll() +
(build_type() == config::debug ? "_d" : "") + ".pdb"),
2020-11-21 00:39:41 -05:00
conf().path().install_pdbs());
2020-04-29 22:10:55 -04:00
// dlls and python libraries are installed by the python plugin
2023-09-19 18:28:24 +02:00
}
2020-05-06 14:07:45 -04:00
2022-04-28 21:35:24 +02:00
void python::install_pip()
2023-09-19 18:28:24 +02:00
{
2022-04-28 21:35:24 +02:00
cx().trace(context::generic, "installing pip");
run_tool(pip(pip::ensure));
2020-04-29 22:10:55 -04:00
}
2020-05-01 00:57:10 -04:00
msbuild python::create_msbuild_tool(msbuild::ops o)
{
2020-05-04 08:37:17 -04:00
return std::move(
2020-05-25 00:31:49 -04:00
msbuild(o)
2020-05-04 08:37:17 -04:00
.solution(solution_file())
.targets({"python", "pythonw", "python3dll", "select", "pyexpat",
"unicodedata", "_queue", "_bz2", "_ssl", "_overlapped"})
.configuration(build_type())
.properties(
2020-05-04 08:37:17 -04:00
{"bz2Dir=" + path_to_utf8(bzip2::source_path()),
2020-05-25 00:31:49 -04:00
"zlibDir=" + path_to_utf8(zlib::source_path()),
2020-05-04 08:37:17 -04:00
"opensslIncludeDir=" + path_to_utf8(openssl::include_path()),
2024-05-25 14:25:40 +02:00
"opensslOutDir=" + path_to_utf8(openssl::source_path())}));
2020-05-01 00:57:10 -04:00
}
2020-05-25 00:31:49 -04:00
fs::path python::python_exe()
{
return build_path() /
(build_type() == config::debug ? "python_d.exe" : "python.exe");
2020-05-25 00:31:49 -04:00
}
2020-04-29 22:10:55 -04:00
fs::path python::include_path()
{
return source_path() / "Include";
}
fs::path python::scripts_path()
{
return source_path() / "Scripts";
}
2020-05-01 00:57:10 -04:00
fs::path python::site_packages_path()
{
return source_path() / "Lib" / "site-packages";
}
2020-05-02 03:12:34 -04:00
} // namespace mob::tasks