mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
Add VCPKG support for USVFS. (#149)
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@ if (!$root) {
|
||||
|
||||
$output = if ($Verbose) { "Out-Default" } else { "Out-Null" }
|
||||
|
||||
cmake -B $root/build $root | & $output
|
||||
cmake -B $root/build -G "Visual Studio 17 2022" $root | & $output
|
||||
|
||||
$installationPath = & $root\third-party\bin\vswhere.exe -products * -nologo -prerelease -latest -property installationPath
|
||||
if (! $?) {
|
||||
|
||||
@@ -155,6 +155,7 @@ install_licenses =
|
||||
install_pythoncore =
|
||||
install_translations =
|
||||
vs =
|
||||
vcpkg =
|
||||
qt_install =
|
||||
qt_bin =
|
||||
qt_translations =
|
||||
|
||||
+2
-1
@@ -509,6 +509,7 @@ namespace mob {
|
||||
set_path_if_empty("pf_x86", find_program_files_x86);
|
||||
set_path_if_empty("pf_x64", find_program_files_x64);
|
||||
set_path_if_empty("vs", find_vs);
|
||||
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"));
|
||||
@@ -530,7 +531,7 @@ namespace mob {
|
||||
resolve_path("install", p.prefix(), "install");
|
||||
resolve_path("install_installer", p.install(), "installer");
|
||||
resolve_path("install_bin", p.install(), "bin");
|
||||
resolve_path("install_libs", p.install(), "libs");
|
||||
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");
|
||||
|
||||
@@ -264,6 +264,7 @@ namespace mob {
|
||||
VALUE(install_translations);
|
||||
|
||||
VALUE(vs);
|
||||
VALUE(vcpkg);
|
||||
VALUE(qt_install);
|
||||
VALUE(qt_bin);
|
||||
VALUE(qt_translations);
|
||||
|
||||
@@ -254,6 +254,24 @@ namespace mob {
|
||||
}
|
||||
}
|
||||
|
||||
fs::path find_vcpkg()
|
||||
{
|
||||
const auto env_path = this_env::get().get("VCPKG_ROOT");
|
||||
|
||||
if (!env_path.empty()) {
|
||||
return fs::absolute(env_path);
|
||||
}
|
||||
|
||||
const auto vs_path = conf().path().vs();
|
||||
const auto vcpkg_vs_path = vs_path / "VC" / "vcpkg";
|
||||
if (!exists(vcpkg_vs_path)) {
|
||||
gcx().bail_out(context::conf, "vcpkg is not part of VS installation at {}",
|
||||
vs_path);
|
||||
}
|
||||
|
||||
return vcpkg_vs_path;
|
||||
}
|
||||
|
||||
fs::path find_qt()
|
||||
{
|
||||
// check from the ini first
|
||||
|
||||
@@ -33,6 +33,11 @@ namespace mob {
|
||||
//
|
||||
fs::path find_vs();
|
||||
|
||||
// returns the absolute path to VCPKG root directory to be used as VCPKG_ROOT when
|
||||
// building
|
||||
//
|
||||
fs::path find_vcpkg();
|
||||
|
||||
// returns the absolute path to Qt's root directory, the one that contains
|
||||
// bin, include, etc.; bails if not found
|
||||
//
|
||||
|
||||
+1
-1
@@ -166,7 +166,7 @@ namespace mob {
|
||||
for (auto& c : commands)
|
||||
all_groups.push_back(c->group());
|
||||
|
||||
// vs reports a no-op on the left side of the command, which is incorrect
|
||||
// vs reports a no-op on the left side of the command, which is incorrect
|
||||
#pragma warning(suppress : 4548)
|
||||
auto cli = (all_groups, command::common_options_group());
|
||||
auto pr = clipp::parse(args, cli);
|
||||
|
||||
@@ -672,6 +672,7 @@ namespace mob::tasks {
|
||||
void fetch_from_source();
|
||||
void build_and_install_from_source();
|
||||
|
||||
cmake create_cmake_tool(arch, cmake::ops = cmake::generate) const;
|
||||
msbuild create_msbuild_tool(arch, msbuild::ops = msbuild::build,
|
||||
config = config::release) const;
|
||||
};
|
||||
|
||||
+22
-24
@@ -40,6 +40,11 @@ namespace mob::tasks {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_set(c, clean::reconfigure)) {
|
||||
run_tool(create_cmake_tool(arch::x64));
|
||||
run_tool(create_cmake_tool(arch::x86));
|
||||
}
|
||||
|
||||
if (is_set(c, clean::rebuild)) {
|
||||
// msbuild clean
|
||||
run_tool(create_msbuild_tool(arch::x86, msbuild::clean,
|
||||
@@ -69,35 +74,28 @@ namespace mob::tasks {
|
||||
|
||||
void usvfs::build_and_install_from_source()
|
||||
{
|
||||
run_tool(create_msbuild_tool(arch::x86));
|
||||
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));
|
||||
}
|
||||
|
||||
cmake usvfs::create_cmake_tool(arch a, cmake::ops o) const
|
||||
{
|
||||
return std::move(
|
||||
cmake(o)
|
||||
.root(source_path())
|
||||
.def("CMAKE_INSTALL_PREFIX:PATH", conf().path().install())
|
||||
.generator(cmake::vs)
|
||||
.preset(a == arch::x64 ? "vs2022-windows-x64" : "vs2022-windows-x86")
|
||||
.arg("-DBUILD_TESTING=OFF"));
|
||||
}
|
||||
|
||||
msbuild usvfs::create_msbuild_tool(arch a, msbuild::ops o, config c) const
|
||||
{
|
||||
// usvfs doesn't use "Win32" for 32-bit, it uses "x86"
|
||||
//
|
||||
// note that usvfs_proxy has a custom build step in Release that runs
|
||||
// usvfs/vsbuild/stage_helper.cmd, which copies everything into
|
||||
// install/
|
||||
|
||||
const std::string plat = (a == arch::x64 ? "x64" : "x86");
|
||||
|
||||
// udis requires python in its custom build step, so make sure it's on the
|
||||
// path
|
||||
//
|
||||
// BOOST_PATH is in the env because external_dependencies.props will
|
||||
// use it if it exists or reverts to a hardcoded path which might not be using
|
||||
// the same version as mob if it wasn't updated
|
||||
return std::move(
|
||||
msbuild(o)
|
||||
.platform(plat)
|
||||
.configuration(c)
|
||||
.targets({"usvfs_proxy"})
|
||||
.solution(source_path() / "vsbuild" / "usvfs.sln")
|
||||
.env(env::vs(a)
|
||||
.prepend_path(python::build_path())
|
||||
.set("BOOST_PATH", path_to_utf8(boost::source_path()))));
|
||||
const std::string vsbuild = (a == arch::x64 ? "vsbuild64" : "vsbuild32");
|
||||
return std::move(msbuild(o).architecture(a).configuration(c).solution(
|
||||
source_path() / vsbuild / "usvfs.sln"));
|
||||
}
|
||||
|
||||
} // namespace mob::tasks
|
||||
|
||||
+113
-24
@@ -4,8 +4,23 @@
|
||||
|
||||
namespace mob {
|
||||
|
||||
namespace {
|
||||
std::string config_to_string(config c)
|
||||
{
|
||||
switch (c) {
|
||||
case config::debug:
|
||||
return "Debug";
|
||||
case config::release:
|
||||
return "Release";
|
||||
case config::relwithdebinfo:
|
||||
return "RelWithDebInfo";
|
||||
}
|
||||
gcx().bail_out(context::generic, "unknow configuration type {}", c);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
cmake::cmake(ops o)
|
||||
: basic_process_runner("cmake"), op_(o), gen_(jom), arch_(arch::def)
|
||||
: basic_process_runner("cmake"), op_(o), gen_(vs), arch_(arch::def)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -62,6 +77,12 @@ namespace mob {
|
||||
return *this;
|
||||
}
|
||||
|
||||
cmake& cmake::preset(const std::string& s)
|
||||
{
|
||||
preset_ = s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
cmake& cmake::arg(std::string s)
|
||||
{
|
||||
std::replace(s.begin(), s.end(), '\\', '/');
|
||||
@@ -75,6 +96,24 @@ namespace mob {
|
||||
return *this;
|
||||
}
|
||||
|
||||
cmake& cmake::targets(const std::string& target)
|
||||
{
|
||||
targets_ = {target};
|
||||
return *this;
|
||||
}
|
||||
|
||||
cmake& cmake::targets(const std::vector<std::string>& targets)
|
||||
{
|
||||
targets_ = targets;
|
||||
return *this;
|
||||
}
|
||||
|
||||
cmake& cmake::configuration(mob::config config)
|
||||
{
|
||||
config_ = config;
|
||||
return *this;
|
||||
}
|
||||
|
||||
cmake& cmake::cmd(const std::string& s)
|
||||
{
|
||||
cmd_ = s;
|
||||
@@ -110,6 +149,16 @@ namespace mob {
|
||||
break;
|
||||
}
|
||||
|
||||
case build: {
|
||||
do_build();
|
||||
break;
|
||||
}
|
||||
|
||||
case install: {
|
||||
do_install();
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
cx().bail_out(context::generic, "bad cmake op {}", op_);
|
||||
}
|
||||
@@ -126,43 +175,83 @@ namespace mob {
|
||||
auto p = process()
|
||||
.stdout_encoding(encodings::utf8)
|
||||
.stderr_encoding(encodings::utf8)
|
||||
.binary(binary())
|
||||
.arg("-DCMAKE_BUILD_TYPE=Release")
|
||||
.arg("-DCMAKE_INSTALL_MESSAGE=" +
|
||||
conf_cmake::to_string(conf().cmake().install_message()))
|
||||
.arg("--log-level=ERROR")
|
||||
.arg("--no-warn-unused-cli");
|
||||
.binary(binary());
|
||||
|
||||
if (genstring_.empty()) {
|
||||
// there's always a generator name, but some generators don't need
|
||||
// an architecture flag, like jom, so get_arch() might return an empty
|
||||
// string
|
||||
p.arg("-G", "\"" + g.name + "\"")
|
||||
.arg(g.get_arch(arch_))
|
||||
.arg(g.get_host(conf().cmake().host()));
|
||||
}
|
||||
else {
|
||||
// verbatim generator string
|
||||
p.arg("-G", "\"" + genstring_ + "\"");
|
||||
if (!preset_.empty()) {
|
||||
p = p.arg("--preset").arg(preset_);
|
||||
}
|
||||
|
||||
p = p.arg("-DCMAKE_INSTALL_MESSAGE=" +
|
||||
conf_cmake::to_string(conf().cmake().install_message()))
|
||||
.arg("--log-level=ERROR")
|
||||
.arg("--no-warn-unused-cli");
|
||||
|
||||
// prefix
|
||||
if (!prefix_.empty())
|
||||
p.arg("-DCMAKE_INSTALL_PREFIX=", prefix_);
|
||||
|
||||
p.args(args_);
|
||||
|
||||
// `..` by default, overriden by cmd()
|
||||
if (cmd_.empty())
|
||||
p.arg("..");
|
||||
else
|
||||
p.arg(cmd_);
|
||||
if (preset_.empty()) {
|
||||
|
||||
p.env(env::vs(arch_).set("CXXFLAGS", "/wd4566")).cwd(build_path());
|
||||
if (genstring_.empty()) {
|
||||
// there's always a generator name, but some generators don't need
|
||||
// an architecture flag, like jom, so get_arch() might return an empty
|
||||
// string
|
||||
p.arg("-G", "\"" + g.name + "\"")
|
||||
.arg(g.get_arch(arch_))
|
||||
.arg(g.get_host(conf().cmake().host()));
|
||||
}
|
||||
else {
|
||||
// verbatim generator string
|
||||
p.arg("-G", "\"" + genstring_ + "\"");
|
||||
}
|
||||
|
||||
// `..` by default, overriden by cmd()
|
||||
if (cmd_.empty())
|
||||
p.arg("..");
|
||||
else
|
||||
p.arg(cmd_);
|
||||
}
|
||||
|
||||
p.env(env::vs(arch_)
|
||||
.set("CXXFLAGS", "/wd4566")
|
||||
.set("VCPKG_ROOT", absolute(conf().path().vcpkg()).string()))
|
||||
.cwd(preset_.empty() ? build_path() : root_);
|
||||
|
||||
execute_and_join(p);
|
||||
}
|
||||
|
||||
void cmake::do_build()
|
||||
{
|
||||
auto p = process()
|
||||
.stdout_encoding(encodings::utf8)
|
||||
.stderr_encoding(encodings::utf8)
|
||||
.binary(binary())
|
||||
.arg("--build")
|
||||
.arg(build_path())
|
||||
.arg("--config")
|
||||
.arg(config_to_string(config_));
|
||||
|
||||
for (auto& target : targets_) {
|
||||
p = p.arg("--target").arg(target);
|
||||
}
|
||||
|
||||
execute_and_join(p);
|
||||
}
|
||||
|
||||
void cmake::do_install()
|
||||
{
|
||||
execute_and_join(process()
|
||||
.stdout_encoding(encodings::utf8)
|
||||
.stderr_encoding(encodings::utf8)
|
||||
.binary(binary())
|
||||
.arg("--install")
|
||||
.arg(build_path())
|
||||
.arg("--config")
|
||||
.arg(config_to_string(config_)));
|
||||
}
|
||||
|
||||
void cmake::do_clean()
|
||||
{
|
||||
cx().trace(context::rebuild, "deleting all generator directories");
|
||||
|
||||
@@ -29,6 +29,12 @@ namespace mob {
|
||||
// generates the build files
|
||||
generate = 1,
|
||||
|
||||
// build
|
||||
build,
|
||||
|
||||
// install
|
||||
install,
|
||||
|
||||
// cleans the build files so they're regenerated from scratch
|
||||
clean
|
||||
};
|
||||
@@ -54,6 +60,15 @@ namespace mob {
|
||||
//
|
||||
cmake& root(const fs::path& p);
|
||||
|
||||
// set the targets for build
|
||||
//
|
||||
cmake& targets(const std::string& target);
|
||||
cmake& targets(const std::vector<std::string>& target);
|
||||
|
||||
// set the configuration to build or install
|
||||
//
|
||||
cmake& configuration(mob::config config);
|
||||
|
||||
// overrides the directory in which cmake will write build files
|
||||
//
|
||||
// by default, this is a directory inside what was given in root() with a
|
||||
@@ -75,6 +90,10 @@ namespace mob {
|
||||
cmake& def(const std::string& name, const fs::path& p);
|
||||
cmake& def(const std::string& name, const char* s);
|
||||
|
||||
// set a preset to run with cmake --preset
|
||||
//
|
||||
cmake& preset(const std::string& s);
|
||||
|
||||
// adds an arbitrary argument, passed verbatim
|
||||
//
|
||||
cmake& arg(std::string s);
|
||||
@@ -146,6 +165,9 @@ namespace mob {
|
||||
// what run() does
|
||||
ops op_;
|
||||
|
||||
// preset to run
|
||||
std::string preset_;
|
||||
|
||||
// directory where CMakeLists.txt is
|
||||
fs::path root_;
|
||||
|
||||
@@ -156,6 +178,12 @@ namespace mob {
|
||||
// passed as -DCMAKE_INSTALL_PREFIX
|
||||
fs::path prefix_;
|
||||
|
||||
// targets
|
||||
std::vector<std::string> targets_;
|
||||
|
||||
// configuration
|
||||
mob::config config_{mob::config::relwithdebinfo};
|
||||
|
||||
// passed verbatim
|
||||
std::vector<std::string> args_;
|
||||
|
||||
@@ -175,6 +203,8 @@ namespace mob {
|
||||
// runs cmake
|
||||
//
|
||||
void do_generate();
|
||||
void do_build();
|
||||
void do_install();
|
||||
|
||||
// returns a list of generators handled by this tool, same ones as in the
|
||||
// `generators` enum on top
|
||||
|
||||
Reference in New Issue
Block a user