Files
mob/src/main.cpp
T

1119 lines
19 KiB
C++
Raw Normal View History

2020-04-26 13:47:26 -04:00
#include "pch.h"
2020-04-27 09:43:05 -04:00
#include "conf.h"
#include "net.h"
#include "op.h"
#include "tools.h"
#include "utility.h"
2020-04-26 13:47:26 -04:00
namespace builder
{
2020-04-28 19:29:05 -04:00
class interrupted {};
2020-04-27 14:40:28 -04:00
class task;
std::vector<std::unique_ptr<task>> g_tasks;
2020-04-28 19:29:05 -04:00
template <class T>
bool add_task()
{
g_tasks.push_back(std::make_unique<T>());
return true;
}
2020-04-27 14:40:28 -04:00
2020-04-27 11:34:00 -04:00
class task
2020-04-26 13:47:26 -04:00
{
public:
2020-04-27 14:40:28 -04:00
task(const task&) = delete;
task& operator=(const task&) = delete;
virtual ~task()
2020-04-27 11:34:00 -04:00
{
2020-04-27 14:40:28 -04:00
try
{
join();
}
catch(bailed)
{
// ignore
}
}
static void interrupt_all()
{
std::scoped_lock lock(interrupt_mutex_);
for (auto&& t : g_tasks)
t->interrupt();
2020-04-27 11:34:00 -04:00
}
2020-04-27 19:21:44 -04:00
const std::string& name() const
{
return name_;
}
2020-04-28 22:14:47 -04:00
virtual fs::path get_source_path() const = 0;
2020-04-26 13:47:26 -04:00
void run()
{
2020-04-27 11:34:00 -04:00
info(name_);
2020-04-27 14:40:28 -04:00
thread_ = std::thread([&]
{
try
{
2020-04-28 19:29:05 -04:00
check_interrupted();
2020-04-27 14:40:28 -04:00
fetch();
2020-04-28 19:29:05 -04:00
check_interrupted();
2020-04-27 18:45:09 -04:00
build_and_install();
2020-04-27 14:40:28 -04:00
}
catch(bailed e)
{
error(name_ + " bailed out, interrupting all tasks");
interrupt_all();
}
2020-04-28 19:29:05 -04:00
catch(interrupted)
{
return;
}
2020-04-27 18:45:09 -04:00
catch(std::exception& e)
{
error(name_ + " uncaught exception: " + e.what());
interrupt_all();
}
2020-04-27 14:40:28 -04:00
});
}
void interrupt()
{
std::scoped_lock lock(tool_mutex_);
interrupted_ = true;
if (tool_)
tool_->interrupt();
}
void join()
{
if (thread_.joinable())
thread_.join();
2020-04-27 11:34:00 -04:00
}
2020-04-26 13:47:26 -04:00
2020-04-27 11:34:00 -04:00
void fetch()
{
do_fetch();
run_tool(patcher()
.task(name_)
.root(get_source_path()));
2020-04-27 11:34:00 -04:00
}
2020-04-27 18:45:09 -04:00
void build_and_install()
2020-04-27 11:34:00 -04:00
{
2020-04-27 18:45:09 -04:00
do_build_and_install();
2020-04-27 11:34:00 -04:00
}
protected:
2020-04-27 14:40:28 -04:00
task(std::string name)
: name_(std::move(name)), interrupted_(false), tool_(nullptr)
2020-04-27 14:40:28 -04:00
{
}
2020-04-28 19:29:05 -04:00
void check_interrupted()
{
if (interrupted_)
throw interrupted();
}
2020-04-27 14:40:28 -04:00
virtual void do_fetch() {};
2020-04-27 18:45:09 -04:00
virtual void do_build_and_install() {};
2020-04-27 11:34:00 -04:00
template <class Tool>
auto run_tool(Tool&& t)
2020-04-27 14:40:28 -04:00
{
{
tool_ = &t;
2020-04-27 14:40:28 -04:00
std::scoped_lock lock(tool_mutex_);
}
2020-04-28 19:29:05 -04:00
check_interrupted();
t.run();
2020-04-28 19:29:05 -04:00
check_interrupted();
{
std::scoped_lock lock(tool_mutex_);
tool_ = nullptr;
2020-04-28 19:29:05 -04:00
}
return t.result();
2020-04-27 14:40:28 -04:00
}
2020-04-27 11:34:00 -04:00
private:
std::string name_;
2020-04-27 14:40:28 -04:00
std::thread thread_;
std::atomic<bool> interrupted_;
tool* tool_;
2020-04-27 14:40:28 -04:00
std::mutex tool_mutex_;
static std::mutex interrupt_mutex_;
2020-04-27 11:34:00 -04:00
};
2020-04-27 14:40:28 -04:00
std::mutex task::interrupt_mutex_;
2020-04-27 11:34:00 -04:00
2020-04-28 22:14:47 -04:00
template <class Task>
class basic_task : public task
{
public:
using task::task;
fs::path get_source_path() const override
{
return Task::source_path();
}
};
class sevenz : public basic_task<sevenz>
2020-04-27 11:34:00 -04:00
{
public:
sevenz()
2020-04-28 22:14:47 -04:00
: basic_task("7z")
2020-04-27 11:34:00 -04:00
{
}
2020-04-28 22:14:47 -04:00
static fs::path source_path()
2020-04-27 18:45:09 -04:00
{
return paths::build() / ("7zip-" + versions::sevenzip());
}
2020-04-28 22:14:47 -04:00
protected:
2020-04-27 11:34:00 -04:00
void do_fetch() override
{
const auto file = run_tool(downloader(source_url()));
2020-04-27 14:40:28 -04:00
run_tool(decompresser()
.file(file)
.output(source_path()));
2020-04-27 11:34:00 -04:00
}
2020-04-26 13:47:26 -04:00
2020-04-27 18:45:09 -04:00
void do_build_and_install() override
2020-04-27 11:34:00 -04:00
{
run_tool(jom()
.path(module_to_build())
.def("CPU=x64")
.def("NEW_COMPILER=1")
.def("MY_STATIC_LINK=1")
.def("NO_BUFFEROVERFLOWU=1"));
2020-04-26 13:47:26 -04:00
op::copy_file_to_dir_if_better(
module_to_build() / "x64/7z.dll",
paths::install_dlls());
}
2020-04-26 13:47:26 -04:00
private:
url source_url() const
{
return "https://www.7-zip.org/a/7z" + version_for_url() + "-src.7z";
}
fs::path module_to_build() const
{
return source_path() / "CPP" / "7zip" / "Bundles" / "Format7zF";
}
std::string version_for_url() const
{
return replace_all(versions::sevenzip(), ".", "");
2020-04-27 11:34:00 -04:00
}
2020-04-26 13:47:26 -04:00
};
2020-04-28 22:14:47 -04:00
class zlib : public basic_task<zlib>
2020-04-26 14:32:46 -04:00
{
public:
2020-04-27 11:34:00 -04:00
zlib()
2020-04-28 22:14:47 -04:00
: basic_task("zlib")
2020-04-26 14:32:46 -04:00
{
2020-04-27 11:34:00 -04:00
}
2020-04-26 14:32:46 -04:00
2020-04-28 22:14:47 -04:00
static fs::path source_path()
2020-04-27 18:45:09 -04:00
{
return paths::build() / ("zlib-" + versions::zlib());
}
2020-04-28 22:14:47 -04:00
protected:
2020-04-27 18:45:09 -04:00
void do_fetch() override
2020-04-27 11:34:00 -04:00
{
const auto file = run_tool(downloader(source_url()));
2020-04-27 14:40:28 -04:00
run_tool(decompresser()
.file(file)
.output(source_path()));
2020-04-27 11:34:00 -04:00
}
2020-04-26 14:32:46 -04:00
2020-04-27 18:45:09 -04:00
void do_build_and_install() override
2020-04-27 11:34:00 -04:00
{
const auto build_path = run_tool(cmake()
.generator(cmake::nmake)
.root(source_path())
.prefix(source_path()));
run_tool(jom()
.path(build_path)
.target("install"));
2020-04-26 14:32:46 -04:00
2020-04-27 18:45:09 -04:00
op::copy_file_to_dir_if_better(
build_path / "zconf.h",
2020-04-27 18:45:09 -04:00
source_path());
2020-04-27 11:34:00 -04:00
}
private:
url source_url() const
{
return "https://zlib.net/zlib-" + versions::zlib() + ".tar.gz";
}
2020-04-27 11:34:00 -04:00
};
2020-04-28 22:14:47 -04:00
class boost : public basic_task<boost>
2020-04-27 11:34:00 -04:00
{
public:
boost()
2020-04-28 22:14:47 -04:00
: basic_task("boost")
2020-04-27 11:34:00 -04:00
{
}
2020-04-28 22:14:47 -04:00
static fs::path source_path()
2020-04-27 18:45:09 -04:00
{
const auto underscores = replace_all(versions::boost(), ".", "_");
return paths::build() / ("boost_" + underscores);
}
2020-04-28 22:14:47 -04:00
protected:
2020-04-27 18:45:09 -04:00
void do_fetch() override
2020-04-28 19:29:05 -04:00
{
if (prebuilt::boost())
fetch_prebuilt();
else
fetch_from_source();
}
void do_build_and_install() override
{
if (prebuilt::boost())
build_and_install_prebuilt();
else
build_and_install_from_source();
}
private:
std::smatch parse_boost_version() const
{
// 1.72.0-b1-rc1
// everything but 1.72 is optional
std::regex re(R"((\d+)\.(\d+)(?:\.(\d+)(?:-(\w+)(?:-(\w+))?)?)?)");
std::smatch m;
if (!std::regex_match(versions::boost(), m, re))
bail_out("bad boost version '" + versions::boost() + "'");
return m;
}
std::string source_download_filename() const
{
return boost_version_all_underscores() + ".zip";
}
void fetch_prebuilt()
2020-04-27 11:34:00 -04:00
{
const auto file = run_tool(downloader(prebuilt_url()));
2020-04-27 11:34:00 -04:00
run_tool(decompresser()
.file(file)
.output(source_path()));
2020-04-27 11:34:00 -04:00
}
2020-04-28 19:29:05 -04:00
void build_and_install_prebuilt()
2020-04-27 11:34:00 -04:00
{
2020-04-27 18:45:09 -04:00
op::copy_file_to_dir_if_better(
lib_path() / python_dll(), paths::install_bin());
2020-04-27 11:34:00 -04:00
}
2020-04-28 19:29:05 -04:00
void fetch_from_source()
{
const auto file = run_tool(downloader(source_url()));
2020-04-28 19:29:05 -04:00
run_tool(decompresser()
.file(file)
.output(source_path()));
2020-04-28 19:29:05 -04:00
}
void build_and_install_from_source()
{
}
url prebuilt_url() const
{
const auto underscores = replace_all(versions::boost(), ".", "_");
return
"https://github.com/ModOrganizer2/modorganizer-umbrella/"
"releases/download/1.1/boost_prebuilt_" + underscores + ".7z";
}
url source_url() const
{
return
"https://dl.bintray.com/boostorg/release/" +
boost_version_no_tags() + "/source/" +
boost_version_all_underscores() + ".zip";
}
2020-04-27 11:34:00 -04:00
fs::path lib_path() const
{
const std::string lib = "lib64-msvc-" + versions::boost_vs();
2020-04-27 18:45:09 -04:00
return source_path() / lib / "lib";
2020-04-27 11:34:00 -04:00
}
std::string python_dll() const
{
std::ostringstream oss;
// builds something like boost_python38-vc142-mt-x64-1_72.dll
// boost_python38-
oss << "boost_python" << python_version_no_patch() + "-";
// vc142-
oss << "vc" + replace_all(versions::boost_vs(), ".", "") << "-";
// mt-x64-1_72
2020-04-28 19:29:05 -04:00
oss << "mt-x64-" << boost_version_no_patch_underscores();
2020-04-27 11:34:00 -04:00
oss << ".dll";
return oss.str();
}
std::string python_version_no_patch() const
{
// matches 3.8 and 3.8.1
std::regex re(R"((\d+)\.(\d+)(?:\.(\d+))?)");
std::smatch m;
if (!std::regex_match(versions::python(), m, re))
bail_out("bad python version '" + versions::python() + "'");
// 38
return m[1].str() + m[2].str();
}
2020-04-28 19:29:05 -04:00
std::string boost_version_no_patch_underscores() const
2020-04-27 11:34:00 -04:00
{
2020-04-28 19:29:05 -04:00
const auto m = parse_boost_version();
2020-04-27 11:34:00 -04:00
2020-04-28 19:29:05 -04:00
// 1_72
2020-04-27 11:34:00 -04:00
return m[1].str() + "_" + m[2].str();
2020-04-26 14:32:46 -04:00
}
2020-04-28 19:29:05 -04:00
std::string boost_version_no_tags() const
{
const auto m = parse_boost_version();
// 1.72.1
std::string s = m[1].str() + "." + m[2].str();
if (m.size() > 3)
s += "." + m[3].str();
return s;
}
std::string boost_version_all_underscores() const
{
const auto m = parse_boost_version();
// boost_1_72_0_b1_rc1
std::string s = "boost_" + m[1].str() + "_" + m[2].str();
if (m.size() > 3)
s += "_" + m[3].str();
if (m.size() > 4)
s += "_" + m[4].str();
if (m.size() > 5)
s += "_" + m[5].str();
return s;
}
2020-04-26 14:32:46 -04:00
};
2020-04-28 22:14:47 -04:00
class fmt : public basic_task<fmt>
2020-04-27 11:45:46 -04:00
{
public:
fmt()
2020-04-28 22:14:47 -04:00
: basic_task("fmt")
2020-04-27 11:45:46 -04:00
{
}
2020-04-28 22:14:47 -04:00
static fs::path source_path()
2020-04-27 18:45:09 -04:00
{
return paths::build() / ("fmt-" + versions::fmt());
}
2020-04-28 22:14:47 -04:00
protected:
2020-04-27 18:45:09 -04:00
void do_fetch() override
2020-04-27 11:45:46 -04:00
{
const auto file = run_tool(downloader(source_url()));
2020-04-27 11:45:46 -04:00
run_tool(decompresser()
.file(file)
.output(source_path()));
2020-04-27 11:45:46 -04:00
}
2020-04-27 18:45:09 -04:00
void do_build_and_install() override
2020-04-27 11:45:46 -04:00
{
const auto build_path = run_tool(cmake()
.generator(cmake::nmake)
.root(source_path())
.def("FMT_TEST=OFF")
.def("FMT_DOC=OFF"));
run_tool(jom().path(build_path));
}
private:
url source_url() const
{
return
"https://github.com/fmtlib/fmt/releases/download/" +
versions::fmt() + "/fmt-" + versions::fmt() + ".zip";
2020-04-27 19:21:44 -04:00
}
};
2020-04-28 22:14:47 -04:00
class gtest : public basic_task<gtest>
2020-04-27 19:21:44 -04:00
{
public:
gtest()
2020-04-28 22:14:47 -04:00
: basic_task("gtest")
2020-04-27 19:21:44 -04:00
{
}
2020-04-28 22:14:47 -04:00
static fs::path source_path()
2020-04-27 19:21:44 -04:00
{
return paths::build() / "googletest";
}
2020-04-28 22:14:47 -04:00
protected:
2020-04-27 19:21:44 -04:00
void do_fetch() override
{
run_tool(git_clone()
.org("google")
.repo("googletest")
.branch(versions::gtest())
.output(source_path()));
2020-04-27 19:21:44 -04:00
}
void do_build_and_install() override
{
const auto build_path = run_tool(cmake()
.generator(cmake::nmake)
.root(source_path()));
run_tool(jom()
.path(build_path));
2020-04-27 11:45:46 -04:00
}
};
2020-04-28 22:14:47 -04:00
class libbsarch : public basic_task<libbsarch>
2020-04-27 19:40:25 -04:00
{
public:
libbsarch()
2020-04-28 22:14:47 -04:00
: basic_task("libbsarch")
2020-04-27 19:40:25 -04:00
{
}
2020-04-28 22:14:47 -04:00
static fs::path source_path()
{
return paths::build() / dir_name();
}
2020-04-27 19:40:25 -04:00
protected:
2020-04-28 22:14:47 -04:00
static std::string dir_name()
2020-04-27 19:53:02 -04:00
{
return "libbsarch-" + versions::libbsarch() + "-release-x64";
}
2020-04-27 19:40:25 -04:00
void do_fetch() override
{
const auto file = run_tool(downloader(source_url()));
2020-04-27 19:40:25 -04:00
run_tool(decompresser()
.file(file)
.output(source_path()));
2020-04-27 19:40:25 -04:00
}
void do_build_and_install() override
{
op::copy_file_to_dir_if_better(
source_path() / "libbsarch.dll",
paths::install_dlls());
}
private:
url source_url() const
{
return
"https://github.com/ModOrganizer2/libbsarch/releases/download/" +
versions::libbsarch() + "/" + dir_name() + ".7z";
}
2020-04-27 19:40:25 -04:00
};
2020-04-28 22:14:47 -04:00
class libloot : public basic_task<libloot>
2020-04-27 19:53:02 -04:00
{
public:
libloot()
2020-04-28 22:14:47 -04:00
: basic_task("libloot")
2020-04-27 19:53:02 -04:00
{
}
2020-04-28 22:14:47 -04:00
static fs::path source_path()
{
return paths::build() / dir_name();
}
2020-04-27 19:53:02 -04:00
protected:
2020-04-28 22:14:47 -04:00
static std::string dir_name()
2020-04-27 19:53:02 -04:00
{
// libloot-0.15.1-0-gf725dd7_0.15.1-win64.7z, yeah
return
"libloot-" +
versions::libloot() + "-" +
"0-" +
versions::libloot_hash() + "_" + versions::libloot() + "-" +
"win64";
}
void do_fetch() override
{
const auto file = run_tool(downloader(source_url()));
2020-04-28 19:29:05 -04:00
run_tool(decompresser()
.file(file)
.output(source_path()));
2020-04-28 19:29:05 -04:00
}
void do_build_and_install() override
{
op::copy_file_to_dir_if_better(
source_path() / "loot.dll",
paths::install_loot());
}
private:
url source_url() const
{
return
"https://github.com/loot/libloot/releases/download/" +
versions::libloot() + "/" + dir_name() + ".7z";
}
2020-04-28 19:29:05 -04:00
};
2020-04-28 22:14:47 -04:00
class libffi : public basic_task<libffi>
2020-04-28 19:29:05 -04:00
{
public:
libffi()
2020-04-28 22:14:47 -04:00
: basic_task("libffi")
2020-04-28 19:29:05 -04:00
{
}
2020-04-28 22:14:47 -04:00
static fs::path source_path()
2020-04-28 19:29:05 -04:00
{
return paths::build() / "libffi";
}
2020-04-28 22:14:47 -04:00
static fs::path include_path()
{
return source_path() / "amd64" / "include";
}
static fs::path lib_path()
{
return source_path() / "amd64";
}
protected:
2020-04-28 19:29:05 -04:00
void do_fetch() override
{
run_tool(git_clone()
.org("python")
.repo("cpython-bin-deps")
.branch("libffi")
.output(source_path()));
2020-04-28 19:29:05 -04:00
}
};
2020-04-28 22:14:47 -04:00
class openssl : public basic_task<openssl>
2020-04-28 19:29:05 -04:00
{
public:
openssl()
2020-04-28 22:14:47 -04:00
: basic_task("openssl")
2020-04-28 19:29:05 -04:00
{
}
2020-04-28 22:14:47 -04:00
static fs::path source_path()
2020-04-28 19:29:05 -04:00
{
return paths::build() / ("openssl-" + versions::openssl());
}
2020-04-28 22:14:47 -04:00
static fs::path include_path()
{
return source_path() / "include";
}
protected:
2020-04-28 19:29:05 -04:00
fs::path build_path() const
{
return source_path() / "build";
}
void do_fetch() override
{
const auto file = run_tool(downloader(source_url()));
2020-04-28 19:29:05 -04:00
run_tool(decompresser()
.file(file)
.output(source_path()));
2020-04-28 19:29:05 -04:00
}
void do_build_and_install() override
{
if (fs::exists(source_path() / "makefile"))
debug("openssl already configured");
else
configure();
install_engines();
info("openssl built successfully");
copy_files();
}
private:
void configure()
{
run_tool(process_runner(third_party::perl(), cmd::stdout_is_verbose)
2020-04-29 16:42:50 -04:00
.arg("Configure")
.arg("--openssldir=", build_path())
.arg("--prefix=", build_path())
2020-04-29 16:42:50 -04:00
.arg("-FS")
.arg("-MP1")
.arg("VC-WIN64A")
.cwd(source_path()));
2020-04-28 19:29:05 -04:00
}
void install_engines()
{
for (int tries=0; tries<3; ++tries)
{
int exit_code = run_tool(jom()
.path(source_path())
.target("install_engines")
.flag(jom::accept_failure));
2020-04-28 19:29:05 -04:00
if (exit_code == 0)
2020-04-28 19:29:05 -04:00
return;
}
run_tool(jom()
.path(source_path())
.target("install_engines")
.flag(jom::single_job));
2020-04-28 19:29:05 -04:00
}
void copy_files()
{
2020-04-28 22:14:47 -04:00
op::copy_file_to_dir_if_better(
source_path() / "ms" / "applink.c",
include_path());
2020-04-28 19:29:05 -04:00
copy_dlls_to(paths::install_bin());
copy_dlls_to(paths::install_dlls());
copy_pdbs_to(paths::install_pdbs());
}
void copy_dlls_to(const fs::path& dir)
{
for (auto&& name : output_names())
{
op::copy_file_to_dir_if_better(
build_path() / "bin" / (name + ".dll"), dir);
}
}
void copy_pdbs_to(const fs::path& dir)
{
for (auto&& name : output_names())
{
op::copy_file_to_dir_if_better(
build_path() / "bin" / (name + ".pdb"), dir);
}
}
url source_url() const
{
return
"https://www.openssl.org/source/"
"openssl-" + versions::openssl() + ".tar.gz";
}
2020-04-28 19:29:05 -04:00
std::vector<std::string> output_names() const
{
return
{
"libcrypto-" + version_no_minor_underscores() + "-x64",
"libssl-" + version_no_minor_underscores() + "-x64"
};
}
std::smatch parse_version() const
{
// 1.1.1d
// everything but 1 is optional
std::regex re(R"((\d+)(?:\.(\d+)(?:\.(\d+)([a-zA-Z]+)?)?)?)");
std::smatch m;
if (!std::regex_match(versions::openssl(), m, re))
bail_out("bad openssl version '" + versions::openssl() + "'");
return m;
}
std::string version_no_tags() const
{
auto m = parse_version();
// up to 4 so the tag is skipped if present
const std::size_t count = std::min<std::size_t>(m.size(), 4);
std::string s;
for (std::size_t i=1; i<count; ++i)
{
if (!s.empty())
s += ".";
s += m[i].str();
}
return s;
}
std::string version_no_minor_underscores() const
{
auto m = parse_version();
if (m.size() == 2)
return m[1].str();
else
return m[1].str() + "_" + m[2].str();
}
};
2020-04-28 22:14:47 -04:00
class bzip2 : public basic_task<bzip2>
2020-04-28 19:51:08 -04:00
{
public:
bzip2()
2020-04-28 22:14:47 -04:00
: basic_task("bzip2")
2020-04-28 19:51:08 -04:00
{
}
2020-04-28 22:14:47 -04:00
static fs::path source_path()
2020-04-28 19:51:08 -04:00
{
return paths::build() / ("bzip2-" + versions::bzip2());
}
2020-04-28 22:14:47 -04:00
protected:
2020-04-28 19:51:08 -04:00
void do_fetch() override
{
const auto file = run_tool(downloader(source_url()));
2020-04-28 19:51:08 -04:00
run_tool(decompresser()
.file(file)
.output(source_path()));
}
private:
url source_url() const
{
return
"https://sourceforge.net/projects/bzip2/files/"
"bzip2-" + versions::bzip2() + ".tar.gz/download";
2020-04-28 19:51:08 -04:00
}
};
2020-04-28 22:14:47 -04:00
class python : public basic_task<python>
2020-04-28 19:29:05 -04:00
{
public:
python()
2020-04-28 22:14:47 -04:00
: basic_task("python")
2020-04-28 19:29:05 -04:00
{
}
2020-04-28 22:14:47 -04:00
static fs::path source_path()
{
return paths::build() / ("python-" + versions::python());
}
2020-04-28 19:29:05 -04:00
protected:
void do_fetch() override
{
run_tool(git_clone()
.org("python")
.repo("cpython")
.branch("v" + versions::python())
.output(source_path()));
2020-04-27 19:53:02 -04:00
2020-04-28 22:14:47 -04:00
if (fs::exists(source_path() / "PCBuild" / "UpgradeLog.htm"))
debug("project already upgraded");
else
upgrade_project();
2020-04-27 19:53:02 -04:00
}
void do_build_and_install() override
{
run_tool(msbuild()
.solution(solution_file())
.projects({
2020-04-28 22:14:47 -04:00
"python", "pythonw", "python3dll", "select", "pyexpat",
"unicodedata", "_queue", "_bz2", "_ssl"})
.parameters({
2020-04-28 22:14:47 -04:00
"bz2Dir=" + bzip2::source_path().string(),
"zlibDir=" + zlib::source_path().string(),
"opensslIncludeDir=" + openssl::include_path().string(),
"opensslOutDir=" + openssl::source_path().string(),
"libffiIncludeDir=" + libffi::include_path().string(),
"libffiOutDir=" + libffi::lib_path().string()}));
2020-04-28 22:14:47 -04:00
if (fs::exists(build_path() / "_mob_packaged"))
{
debug("python already packaged");
}
else
{
const auto bat = source_path() / "python.bat";
run_tool(process_runner(bat, cmd::stdout_is_verbose)
2020-04-29 16:42:50 -04:00
.name("package python")
.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-28 22:14:47 -04:00
op::touch(build_path() / "_mob_packaged");
}
2020-04-27 19:53:02 -04:00
op::copy_file_to_dir_if_better(
2020-04-28 22:14:47 -04:00
source_path() / "PC" / "pyconfig.h",
source_path() / "Include");
op::copy_file_to_dir_if_better(
build_path() / "*.lib",
paths::install_libs());
op::copy_file_to_dir_if_better(
build_path() / "libffi*.dll",
paths::install_bin());
op::copy_file_to_dir_if_better(
build_path() / ("python" + version_for_dll() + ".dll"),
paths::install_bin());
op::copy_file_to_dir_if_better(
build_path() / ("python" + version_for_dll() + ".pdb"),
paths::install_pdbs());
}
private:
void upgrade_project()
{
run_tool(process_runner(third_party::devenv(), cmd::stdout_is_verbose)
2020-04-29 16:42:50 -04:00
.name("upgrade project")
.arg(solution_file())
.arg("/upgrade"));
2020-04-28 22:14:47 -04:00
}
fs::path solution_file() const
{
return source_path() / "PCBuild" / "pcbuild.sln";
}
fs::path build_path() const
{
return source_path() / "PCBuild" / "amd64";
}
std::smatch parse_version() const
{
// 3.8.1
// .1 is optional
std::regex re(R"((\d+)\.(\d+)(?:\.(\d+))?)");
std::smatch m;
if (!std::regex_match(versions::python(), m, re))
bail_out("bad python version '" + versions::python() + "'");
return m;
}
std::string version_for_dll() const
{
std::smatch m = parse_version();
// 38
return m[1].str() + m[2].str();
2020-04-27 19:53:02 -04:00
}
};
2020-04-27 14:40:28 -04:00
template <class Tool, class... Args>
2020-04-28 22:14:47 -04:00
class dummy : public basic_task<dummy<Tool, Args...>>
2020-04-27 14:40:28 -04:00
{
public:
dummy(Args&&... args)
2020-04-28 22:14:47 -04:00
: basic_task("dummy"), args_(std::forward<Args>(args)...)
2020-04-27 14:40:28 -04:00
{
}
protected:
2020-04-27 18:45:09 -04:00
void do_fetch() override
2020-04-27 14:40:28 -04:00
{
std::apply([&](auto&&... args){ run_tool<Tool>(args...); }, args_);
}
private:
std::tuple<Args...> args_;
};
template <class Tool, class... Args>
std::unique_ptr<dummy<Tool, Args...>> make_dummy(Args&&... args)
{
using Dummy = dummy<Tool, Args...>;
return std::unique_ptr<Dummy>(new Dummy(std::forward<Args>(args)...));
}
BOOL WINAPI signal_handler(DWORD) noexcept
{
info("caught sigint");
task::interrupt_all();
return TRUE;
}
struct curl_init
{
curl_init()
{
curl_global_init(CURL_GLOBAL_ALL );
}
~curl_init()
{
curl_global_cleanup();
}
};
2020-04-27 19:21:44 -04:00
int run(int argc, char** argv)
2020-04-26 13:47:26 -04:00
{
try
{
2020-04-27 14:40:28 -04:00
::SetConsoleCtrlHandler(signal_handler, TRUE);
curl_init curl;
2020-04-26 13:47:26 -04:00
vcvars();
2020-04-28 19:29:05 -04:00
prepend_to_path(find_third_party_directory() / "bin");
2020-04-26 14:32:46 -04:00
2020-04-29 16:42:50 -04:00
g_tasks.push_back(std::make_unique<sevenz>());
g_tasks.push_back(std::make_unique<zlib>());
g_tasks.push_back(std::make_unique<boost>());
2020-04-29 16:42:50 -04:00
g_tasks.push_back(std::make_unique<fmt>());
g_tasks.push_back(std::make_unique<gtest>());
g_tasks.push_back(std::make_unique<libbsarch>());
g_tasks.push_back(std::make_unique<libloot>());
g_tasks.push_back(std::make_unique<openssl>());
g_tasks.push_back(std::make_unique<libffi>());
g_tasks.push_back(std::make_unique<bzip2>());
g_tasks.push_back(std::make_unique<python>());
2020-04-27 19:21:44 -04:00
if (argc > 1)
{
for (auto&& t : g_tasks)
{
if (t->name() == argv[1])
{
t->run();
t->join();
return 0;
}
}
std::cerr << std::string("task ") + argv[1] + " not found\n";
2020-04-27 19:40:25 -04:00
std::cerr << "valid tasks:\n";
for (auto&& t : g_tasks)
std::cerr << " - " << t->name() << "\n";
2020-04-27 19:21:44 -04:00
return 1;
}
2020-04-27 14:40:28 -04:00
for (auto&& t : g_tasks)
{
2020-04-27 14:40:28 -04:00
t->run();
t->join();
}
//for (auto&& t : g_tasks)
// t->join();
2020-04-26 13:47:26 -04:00
return 0;
}
catch(bailed)
{
error("bailing out");
return 1;
}
}
} // namespace
2020-04-27 19:21:44 -04:00
int main(int argc, char** argv)
2020-04-26 13:47:26 -04:00
{
2020-04-27 19:21:44 -04:00
int r = builder::run(argc, argv);
2020-04-27 14:40:28 -04:00
builder::dump_logs();
2020-04-27 11:34:00 -04:00
//std::cin.get();
2020-04-26 13:47:26 -04:00
return r;
}