Files
mob/src/tasks/python.cpp
T

313 lines
5.9 KiB
C++
Raw Normal View History

2020-04-29 22:10:55 -04:00
#include "pch.h"
#include "tasks.h"
2020-05-02 03:12:34 -04:00
namespace mob
2020-04-29 22:10:55 -04:00
{
python::python()
: basic_task("python")
{
}
2020-05-17 14:14:29 -04:00
std::string python::version()
2020-05-07 11:08:33 -04:00
{
2020-05-17 15:50:15 -04:00
return conf::version_by_name("python");
2020-05-07 11:08:33 -04:00
}
bool python::prebuilt()
{
2020-05-17 15:50:15 -04:00
return conf::prebuilt_by_name("python");
2020-05-07 11:08:33 -04:00
}
python::version_info python::parsed_version()
2020-04-29 22:10:55 -04:00
{
// v3.8.1
// 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-17 14:14:29 -04:00
const auto s = version();
if (!std::regex_match(s, m, re))
bail_out("bad python version '{}'", s);
2020-04-29 22:10:55 -04:00
version_info v;
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;
}
2020-05-07 14:06:37 -04:00
std::string python::version_without_v()
2020-04-29 22:10:55 -04:00
{
2020-05-07 11:08:33 -04:00
const auto v = parsed_version();
// 3.8.1
std::string s = v.major + "." + v.minor;
if (v.patch != "")
s += "." + v.patch;
2020-05-07 14:06:37 -04:00
return s;
}
fs::path python::source_path()
{
return paths::build() / ("python-" + version_without_v());
2020-04-29 22:10:55 -04:00
}
2020-05-02 04:03:20 -04:00
fs::path python::build_path()
{
return source_path() / "PCBuild" / "amd64";
}
2020-05-25 00:31:49 -04:00
void python::do_clean(clean c)
2020-05-04 08:37:17 -04:00
{
instrument<times::clean>([&]
2020-05-20 05:41:19 -04:00
{
if (prebuilt())
2020-05-25 00:31:49 -04:00
{
if (is_set(c, clean::redownload))
run_tool(downloader(prebuilt_url(), downloader::clean));
2020-05-25 01:43:16 -04:00
if (is_set(c, clean::reextract))
{
cx().trace(context::reextract, "deleting {}", source_path());
op::delete_directory(cx(), source_path(), op::optional);
return;
}
}
else
{
if (is_set(c, clean::reclone))
2020-05-25 02:19:39 -04:00
{
git::delete_directory(cx(), source_path());
return;
}
if (is_set(c, clean::rebuild))
run_tool(create_msbuild_tool(msbuild::clean));
}
});
2020-05-04 08:37:17 -04:00
}
2020-04-29 22:10:55 -04:00
void python::do_fetch()
2020-05-07 14:06:37 -04:00
{
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()
{
2020-05-21 04:45:49 -04:00
const auto file = instrument<times::fetch>([&]
2020-05-20 05:41:19 -04:00
{
return run_tool(downloader(prebuilt_url()));
});
2020-05-07 14:06:37 -04:00
2020-05-21 04:45:49 -04:00
instrument<times::extract>([&]
2020-05-20 05:41:19 -04:00
{
run_tool(extractor()
.file(file)
.output(source_path()));
});
2020-05-07 14:06:37 -04:00
}
void python::build_and_install_prebuilt()
{
2020-05-21 04:45:49 -04:00
instrument<times::install>([&]
2020-05-20 05:41:19 -04:00
{
op::copy_glob_to_dir_if_better(cx(),
openssl::bin_path() / "*.dll",
python::build_path(),
op::copy_files);
2020-05-07 15:59:29 -04:00
2020-05-20 05:41:19 -04:00
install_pip();
copy_files();
});
2020-05-07 14:06:37 -04:00
}
void python::fetch_from_source()
2020-04-29 22:10:55 -04:00
{
2020-05-21 04:45:49 -04:00
instrument<times::fetch>([&]
2020-05-20 05:41:19 -04:00
{
run_tool(task_conf().make_git()
2020-05-21 06:54:48 -04:00
.url(task_conf().make_git_url("python", "cpython"))
2020-05-20 05:41:19 -04:00
.branch(version())
.root(source_path()));
});
2020-04-29 22:10:55 -04:00
2020-05-21 04:45:49 -04:00
instrument<times::configure>([&]
2020-05-20 05:41:19 -04:00
{
run_tool(vs(vs::upgrade)
.solution(solution_file()));
});
2020-04-29 22:10:55 -04:00
}
2020-05-07 14:06:37 -04:00
void python::build_and_install_from_source()
2020-04-29 22:10:55 -04:00
{
2020-05-21 04:45:49 -04:00
instrument<times::build>([&]
2020-05-20 05:41:19 -04:00
{
2020-05-25 00:31:49 -04:00
run_tool(create_msbuild_tool());
2020-05-20 05:41:19 -04:00
package();
});
2020-05-07 14:06:37 -04:00
2020-05-21 04:45:49 -04:00
instrument<times::install>([&]
2020-05-20 05:41:19 -04:00
{
install_pip();
2020-05-07 14:06:37 -04:00
2020-05-20 05:41:19 -04:00
op::copy_file_to_dir_if_better(cx(),
source_path() / "PC" / "pyconfig.h",
include_path());
copy_files();
});
2020-05-04 08:37:17 -04:00
}
void python::package()
{
bypass_file packaged_bypass(cx(), build_path(), "packaged");
if (packaged_bypass.exists())
2020-04-29 22:10:55 -04:00
{
2020-05-04 08:37:17 -04:00
cx().trace(context::bypass, "python already packaged");
2020-04-29 22:10:55 -04:00
}
else
{
const auto bat = source_path() / "python.bat";
run_tool(process_runner(process()
.binary(bat)
2020-04-29 22:10:55 -04:00
.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())));
2020-04-29 22:10:55 -04:00
2020-05-04 05:38:23 -04:00
op::touch(cx(), build_path() / "_mob_packaged");
2020-04-29 22:10:55 -04:00
}
2020-05-04 08:37:17 -04:00
}
2020-04-29 22:10:55 -04:00
2020-05-04 08:37:17 -04:00
void python::copy_files()
{
2020-05-06 05:22:42 -04:00
op::copy_glob_to_dir_if_better(cx(),
2020-04-29 22:10:55 -04:00
build_path() / "*.lib",
2020-05-06 05:22:42 -04:00
paths::install_libs(),
op::copy_files);
2020-04-29 22:10:55 -04:00
2020-05-06 05:22:42 -04:00
op::copy_glob_to_dir_if_better(cx(),
2020-04-29 22:10:55 -04:00
build_path() / "libffi*.dll",
2020-11-02 13:40:21 -06:00
paths::install_dlls(),
2020-05-06 05:22:42 -04:00
op::copy_files);
2020-04-29 22:10:55 -04:00
2020-05-04 05:38:23 -04:00
op::copy_file_to_dir_if_better(cx(),
2020-04-29 22:10:55 -04:00
build_path() / ("python" + version_for_dll() + ".dll"),
2020-11-02 13:40:21 -06:00
paths::install_dlls());
2020-04-29 22:10:55 -04:00
2020-05-04 05:38:23 -04:00
op::copy_file_to_dir_if_better(cx(),
2020-04-29 22:10:55 -04:00
build_path() / ("python" + version_for_dll() + ".pdb"),
paths::install_pdbs());
2020-05-06 14:07:45 -04:00
op::copy_glob_to_dir_if_better(cx(),
build_path() / "pythoncore/*.pyd",
paths::install_pythoncore(),
op::copy_files);
op::copy_file_to_file_if_better(cx(),
build_path() / "pythoncore" / ("python" + version_for_dll() + ".zip"),
2020-11-02 13:40:21 -06:00
paths::install_dlls() / "pythoncore.zip",
2020-05-06 14:07:45 -04:00
op::copy_files);
2020-04-29 22:10:55 -04:00
}
2020-05-01 00:57:10 -04:00
void python::install_pip()
{
2020-05-04 08:37:17 -04:00
cx().trace(context::generic, "installing pip");
2020-05-01 00:57:10 -04:00
run_tool(process_runner(process()
.binary(python_exe())
.arg("-m", "ensurepip")));
2020-05-07 15:59:29 -04:00
run_tool(process_runner(process()
.binary(python_exe())
.arg("-m pip")
.arg("install")
.arg("--no-warn-script-location")
2020-05-07 15:59:29 -04:00
.arg("--upgrade pip")));
// ssl errors while downloading through python without certifi
run_tool(process_runner(process()
.binary(python_exe())
2020-05-26 13:44:20 -04:00
.arg("-m pip")
.arg("install")
.arg("--no-warn-script-location")
.arg("certifi")));
2020-05-01 00:57:10 -04:00
}
2020-05-25 00:31:49 -04:00
msbuild python::create_msbuild_tool(msbuild::ops o)
{
return std::move(msbuild(o)
.solution(solution_file())
.targets({
"python", "pythonw", "python3dll", "select", "pyexpat",
2020-11-08 22:17:01 +01:00
"unicodedata", "_queue", "_bz2", "_ssl", "_overlapped"})
2020-05-25 00:31:49 -04:00
.parameters({
"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()),
"libffiIncludeDir=" + path_to_utf8(libffi::include_path()),
"libffiOutDir=" + path_to_utf8(libffi::lib_path())}));
}
2020-04-29 22:10:55 -04:00
fs::path python::python_exe()
{
return build_path() / "python.exe";
}
fs::path python::include_path()
{
return source_path() / "Include";
}
2020-05-01 00:57:10 -04:00
fs::path python::scripts_path()
{
return source_path() / "Scripts";
}
fs::path python::site_packages_path()
{
return source_path() / "Lib" / "site-packages";
}
2020-05-07 14:06:37 -04:00
url python::prebuilt_url()
{
return make_prebuilt_url("python-prebuilt-" + version_without_v() + ".7z");
}
2020-04-29 22:10:55 -04:00
fs::path python::solution_file()
{
return source_path() / "PCBuild" / "pcbuild.sln";
}
std::string python::version_for_dll()
{
2020-05-07 11:08:33 -04:00
const auto v = parsed_version();
2020-04-29 22:10:55 -04:00
// 38
return v.major + v.minor;
}
2020-05-02 03:12:34 -04:00
} // namespace