Skip to content

Commit bd6a03d

Browse files
authored
Add VCPKG support for USVFS. (#149)
1 parent 1087129 commit bd6a03d

File tree

11 files changed

+196
-52
lines changed

11 files changed

+196
-52
lines changed

bootstrap.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ if (!$root) {
1313

1414
$output = if ($Verbose) { "Out-Default" } else { "Out-Null" }
1515

16-
cmake -B $root/build $root | & $output
16+
cmake -B $root/build -G "Visual Studio 17 2022" $root | & $output
1717

1818
$installationPath = & $root\third-party\bin\vswhere.exe -products * -nologo -prerelease -latest -property installationPath
1919
if (! $?) {

mob.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ install_licenses =
155155
install_pythoncore =
156156
install_translations =
157157
vs =
158+
vcpkg =
158159
qt_install =
159160
qt_bin =
160161
qt_translations =

src/core/conf.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ namespace mob {
509509
set_path_if_empty("pf_x86", find_program_files_x86);
510510
set_path_if_empty("pf_x64", find_program_files_x64);
511511
set_path_if_empty("vs", find_vs);
512+
set_path_if_empty("vcpkg", find_vcpkg); // set after vs as it will use the VS
512513
set_path_if_empty("qt_install", find_qt);
513514
set_path_if_empty("temp_dir", find_temp_dir);
514515
set_path_if_empty("patches", find_in_root("patches"));
@@ -530,7 +531,7 @@ namespace mob {
530531
resolve_path("install", p.prefix(), "install");
531532
resolve_path("install_installer", p.install(), "installer");
532533
resolve_path("install_bin", p.install(), "bin");
533-
resolve_path("install_libs", p.install(), "libs");
534+
resolve_path("install_libs", p.install(), "lib");
534535
resolve_path("install_pdbs", p.install(), "pdb");
535536
resolve_path("install_dlls", p.install_bin(), "dlls");
536537
resolve_path("install_loot", p.install_bin(), "loot");

src/core/conf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ namespace mob {
264264
VALUE(install_translations);
265265

266266
VALUE(vs);
267+
VALUE(vcpkg);
267268
VALUE(qt_install);
268269
VALUE(qt_bin);
269270
VALUE(qt_translations);

src/core/paths.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,24 @@ namespace mob {
254254
}
255255
}
256256

257+
fs::path find_vcpkg()
258+
{
259+
const auto env_path = this_env::get().get("VCPKG_ROOT");
260+
261+
if (!env_path.empty()) {
262+
return fs::absolute(env_path);
263+
}
264+
265+
const auto vs_path = conf().path().vs();
266+
const auto vcpkg_vs_path = vs_path / "VC" / "vcpkg";
267+
if (!exists(vcpkg_vs_path)) {
268+
gcx().bail_out(context::conf, "vcpkg is not part of VS installation at {}",
269+
vs_path);
270+
}
271+
272+
return vcpkg_vs_path;
273+
}
274+
257275
fs::path find_qt()
258276
{
259277
// check from the ini first

src/core/paths.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ namespace mob {
3333
//
3434
fs::path find_vs();
3535

36+
// returns the absolute path to VCPKG root directory to be used as VCPKG_ROOT when
37+
// building
38+
//
39+
fs::path find_vcpkg();
40+
3641
// returns the absolute path to Qt's root directory, the one that contains
3742
// bin, include, etc.; bails if not found
3843
//

src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ namespace mob {
166166
for (auto& c : commands)
167167
all_groups.push_back(c->group());
168168

169-
// vs reports a no-op on the left side of the command, which is incorrect
169+
// vs reports a no-op on the left side of the command, which is incorrect
170170
#pragma warning(suppress : 4548)
171171
auto cli = (all_groups, command::common_options_group());
172172
auto pr = clipp::parse(args, cli);

src/tasks/tasks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,7 @@ namespace mob::tasks {
672672
void fetch_from_source();
673673
void build_and_install_from_source();
674674

675+
cmake create_cmake_tool(arch, cmake::ops = cmake::generate) const;
675676
msbuild create_msbuild_tool(arch, msbuild::ops = msbuild::build,
676677
config = config::release) const;
677678
};

src/tasks/usvfs.cpp

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ namespace mob::tasks {
4040
return;
4141
}
4242

43+
if (is_set(c, clean::reconfigure)) {
44+
run_tool(create_cmake_tool(arch::x64));
45+
run_tool(create_cmake_tool(arch::x86));
46+
}
47+
4348
if (is_set(c, clean::rebuild)) {
4449
// msbuild clean
4550
run_tool(create_msbuild_tool(arch::x86, msbuild::clean,
@@ -69,35 +74,28 @@ namespace mob::tasks {
6974

7075
void usvfs::build_and_install_from_source()
7176
{
72-
run_tool(create_msbuild_tool(arch::x86));
77+
run_tool(create_cmake_tool(arch::x64));
78+
run_tool(create_cmake_tool(arch::x86));
7379
run_tool(create_msbuild_tool(arch::x64));
80+
run_tool(create_msbuild_tool(arch::x86));
7481
}
7582

76-
msbuild usvfs::create_msbuild_tool(arch a, msbuild::ops o, config c) const
83+
cmake usvfs::create_cmake_tool(arch a, cmake::ops o) const
7784
{
78-
// usvfs doesn't use "Win32" for 32-bit, it uses "x86"
79-
//
80-
// note that usvfs_proxy has a custom build step in Release that runs
81-
// usvfs/vsbuild/stage_helper.cmd, which copies everything into
82-
// install/
83-
84-
const std::string plat = (a == arch::x64 ? "x64" : "x86");
85-
86-
// udis requires python in its custom build step, so make sure it's on the
87-
// path
88-
//
89-
// BOOST_PATH is in the env because external_dependencies.props will
90-
// use it if it exists or reverts to a hardcoded path which might not be using
91-
// the same version as mob if it wasn't updated
9285
return std::move(
93-
msbuild(o)
94-
.platform(plat)
95-
.configuration(c)
96-
.targets({"usvfs_proxy"})
97-
.solution(source_path() / "vsbuild" / "usvfs.sln")
98-
.env(env::vs(a)
99-
.prepend_path(python::build_path())
100-
.set("BOOST_PATH", path_to_utf8(boost::source_path()))));
86+
cmake(o)
87+
.root(source_path())
88+
.def("CMAKE_INSTALL_PREFIX:PATH", conf().path().install())
89+
.generator(cmake::vs)
90+
.preset(a == arch::x64 ? "vs2022-windows-x64" : "vs2022-windows-x86")
91+
.arg("-DBUILD_TESTING=OFF"));
92+
}
93+
94+
msbuild usvfs::create_msbuild_tool(arch a, msbuild::ops o, config c) const
95+
{
96+
const std::string vsbuild = (a == arch::x64 ? "vsbuild64" : "vsbuild32");
97+
return std::move(msbuild(o).architecture(a).configuration(c).solution(
98+
source_path() / vsbuild / "usvfs.sln"));
10199
}
102100

103101
} // namespace mob::tasks

src/tools/cmake.cpp

Lines changed: 114 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,23 @@
44

55
namespace mob {
66

7+
namespace {
8+
std::string config_to_string(config c)
9+
{
10+
switch (c) {
11+
case config::debug:
12+
return "Debug";
13+
case config::release:
14+
return "Release";
15+
case config::relwithdebinfo:
16+
return "RelWithDebInfo";
17+
}
18+
gcx().bail_out(context::generic, "unknow configuration type {}", c);
19+
}
20+
} // namespace
21+
722
cmake::cmake(ops o)
8-
: basic_process_runner("cmake"), op_(o), gen_(jom), arch_(arch::def)
23+
: basic_process_runner("cmake"), op_(o), gen_(vs), arch_(arch::def)
924
{
1025
}
1126

@@ -62,6 +77,12 @@ namespace mob {
6277
return *this;
6378
}
6479

80+
cmake& cmake::preset(const std::string& s)
81+
{
82+
preset_ = s;
83+
return *this;
84+
}
85+
6586
cmake& cmake::arg(std::string s)
6687
{
6788
std::replace(s.begin(), s.end(), '\\', '/');
@@ -75,6 +96,24 @@ namespace mob {
7596
return *this;
7697
}
7798

99+
cmake& cmake::targets(const std::string& target)
100+
{
101+
targets_ = {target};
102+
return *this;
103+
}
104+
105+
cmake& cmake::targets(const std::vector<std::string>& targets)
106+
{
107+
targets_ = targets;
108+
return *this;
109+
}
110+
111+
cmake& cmake::configuration(mob::config config)
112+
{
113+
config_ = config;
114+
return *this;
115+
}
116+
78117
cmake& cmake::cmd(const std::string& s)
79118
{
80119
cmd_ = s;
@@ -110,6 +149,16 @@ namespace mob {
110149
break;
111150
}
112151

152+
case build: {
153+
do_build();
154+
break;
155+
}
156+
157+
case install: {
158+
do_install();
159+
break;
160+
}
161+
113162
default: {
114163
cx().bail_out(context::generic, "bad cmake op {}", op_);
115164
}
@@ -126,43 +175,83 @@ namespace mob {
126175
auto p = process()
127176
.stdout_encoding(encodings::utf8)
128177
.stderr_encoding(encodings::utf8)
129-
.binary(binary())
130-
.arg("-DCMAKE_BUILD_TYPE=Release")
131-
.arg("-DCMAKE_INSTALL_MESSAGE=" +
132-
conf_cmake::to_string(conf().cmake().install_message()))
133-
.arg("--log-level=ERROR")
134-
.arg("--no-warn-unused-cli");
135-
136-
if (genstring_.empty()) {
137-
// there's always a generator name, but some generators don't need
138-
// an architecture flag, like jom, so get_arch() might return an empty
139-
// string
140-
p.arg("-G", "\"" + g.name + "\"")
141-
.arg(g.get_arch(arch_))
142-
.arg(g.get_host(conf().cmake().host()));
143-
}
144-
else {
145-
// verbatim generator string
146-
p.arg("-G", "\"" + genstring_ + "\"");
178+
.binary(binary());
179+
180+
if (!preset_.empty()) {
181+
p = p.arg("--preset").arg(preset_);
147182
}
148183

184+
p = p.arg("-DCMAKE_INSTALL_MESSAGE=" +
185+
conf_cmake::to_string(conf().cmake().install_message()))
186+
.arg("--log-level=ERROR")
187+
.arg("--no-warn-unused-cli");
188+
149189
// prefix
150190
if (!prefix_.empty())
151191
p.arg("-DCMAKE_INSTALL_PREFIX=", prefix_);
152192

153193
p.args(args_);
154194

155-
// `..` by default, overriden by cmd()
156-
if (cmd_.empty())
157-
p.arg("..");
158-
else
159-
p.arg(cmd_);
195+
if (preset_.empty()) {
196+
197+
if (genstring_.empty()) {
198+
// there's always a generator name, but some generators don't need
199+
// an architecture flag, like jom, so get_arch() might return an empty
200+
// string
201+
p.arg("-G", "\"" + g.name + "\"")
202+
.arg(g.get_arch(arch_))
203+
.arg(g.get_host(conf().cmake().host()));
204+
}
205+
else {
206+
// verbatim generator string
207+
p.arg("-G", "\"" + genstring_ + "\"");
208+
}
209+
210+
// `..` by default, overriden by cmd()
211+
if (cmd_.empty())
212+
p.arg("..");
213+
else
214+
p.arg(cmd_);
215+
}
216+
217+
p.env(env::vs(arch_)
218+
.set("CXXFLAGS", "/wd4566")
219+
.set("VCPKG_ROOT", absolute(conf().path().vcpkg()).string()))
220+
.cwd(preset_.empty() ? build_path() : root_);
221+
222+
execute_and_join(p);
223+
}
224+
225+
void cmake::do_build()
226+
{
227+
auto p = process()
228+
.stdout_encoding(encodings::utf8)
229+
.stderr_encoding(encodings::utf8)
230+
.binary(binary())
231+
.arg("--build")
232+
.arg(build_path())
233+
.arg("--config")
234+
.arg(config_to_string(config_));
160235

161-
p.env(env::vs(arch_).set("CXXFLAGS", "/wd4566")).cwd(build_path());
236+
for (auto& target : targets_) {
237+
p = p.arg("--target").arg(target);
238+
}
162239

163240
execute_and_join(p);
164241
}
165242

243+
void cmake::do_install()
244+
{
245+
execute_and_join(process()
246+
.stdout_encoding(encodings::utf8)
247+
.stderr_encoding(encodings::utf8)
248+
.binary(binary())
249+
.arg("--install")
250+
.arg(build_path())
251+
.arg("--config")
252+
.arg(config_to_string(config_)));
253+
}
254+
166255
void cmake::do_clean()
167256
{
168257
cx().trace(context::rebuild, "deleting all generator directories");

0 commit comments

Comments
 (0)