mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
split paths
This commit is contained in:
+1
-420
@@ -3,6 +3,7 @@
|
||||
#include "context.h"
|
||||
#include "env.h"
|
||||
#include "ini.h"
|
||||
#include "paths.h"
|
||||
#include "../utility.h"
|
||||
#include "../tasks/task.h"
|
||||
#include "../tools/tools.h"
|
||||
@@ -228,59 +229,6 @@ std::vector<std::string> format_options()
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
||||
fs::path find_in_path(std::string_view exe)
|
||||
{
|
||||
const std::wstring wexe = utf8_to_utf16(exe);
|
||||
|
||||
const std::size_t size = MAX_PATH;
|
||||
wchar_t buffer[size + 1] = {};
|
||||
|
||||
if (SearchPathW(nullptr, wexe.c_str(), nullptr, size, buffer, nullptr))
|
||||
return buffer;
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
fs::path find_iscc()
|
||||
{
|
||||
const auto tasks = find_tasks("installer");
|
||||
MOB_ASSERT(tasks.size() == 1);
|
||||
|
||||
if (!tasks[0]->enabled())
|
||||
return {};
|
||||
|
||||
auto iscc = conf().tool().get("iscc");
|
||||
if (iscc.is_absolute())
|
||||
{
|
||||
if (!fs::exists(iscc))
|
||||
{
|
||||
gcx().bail_out(context::conf,
|
||||
"{} doesn't exist (from ini, absolute path)", iscc);
|
||||
}
|
||||
|
||||
return iscc;
|
||||
}
|
||||
|
||||
fs::path p = find_in_path(path_to_utf8(iscc));
|
||||
if (fs::exists(p))
|
||||
return fs::canonical(fs::absolute(p));
|
||||
|
||||
for (int v : {5, 6, 7, 8})
|
||||
{
|
||||
const fs::path inno = fmt::format("inno setup {}", v);
|
||||
|
||||
for (fs::path pf : {conf().path().pf_x86(), conf().path().pf_x64()})
|
||||
{
|
||||
p = pf / inno / iscc;
|
||||
if (fs::exists(p))
|
||||
return fs::canonical(fs::absolute(p));
|
||||
}
|
||||
}
|
||||
|
||||
gcx().bail_out(context::conf, "can't find {} anywhere", iscc);
|
||||
}
|
||||
|
||||
void set_special_options()
|
||||
{
|
||||
conf().global().set_output_log_level(
|
||||
@@ -341,356 +289,6 @@ void make_canonical_path(
|
||||
details::set_string("paths", key, path_to_utf8(p));
|
||||
}
|
||||
|
||||
bool try_parts(fs::path& check, const std::vector<std::string>& parts)
|
||||
{
|
||||
for (std::size_t i=0; i<parts.size(); ++i)
|
||||
{
|
||||
fs::path p = check;
|
||||
|
||||
for (std::size_t j=i; j<parts.size(); ++j)
|
||||
p /= parts[j];
|
||||
|
||||
gcx().trace(context::conf, "trying parts {}", p);
|
||||
|
||||
if (fs::exists(p))
|
||||
{
|
||||
check = p;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
fs::path mob_exe_path()
|
||||
{
|
||||
// double the buffer size 10 times
|
||||
const int max_tries = 10;
|
||||
|
||||
DWORD buffer_size = MAX_PATH;
|
||||
|
||||
for (int tries=0; tries<max_tries; ++tries)
|
||||
{
|
||||
auto buffer = std::make_unique<wchar_t[]>(buffer_size + 1);
|
||||
DWORD n = GetModuleFileNameW(0, buffer.get(), buffer_size);
|
||||
|
||||
if (n == 0) {
|
||||
const auto e = GetLastError();
|
||||
gcx().bail_out(context::conf,
|
||||
"can't get module filename, {}", error_message(e));
|
||||
}
|
||||
else if (n >= buffer_size) {
|
||||
// buffer is too small, try again
|
||||
buffer_size *= 2;
|
||||
} else {
|
||||
// if GetModuleFileName() works, `n` does not include the null
|
||||
// terminator
|
||||
const std::wstring s(buffer.get(), n);
|
||||
return fs::canonical(s);
|
||||
}
|
||||
}
|
||||
|
||||
gcx().bail_out(context::conf, "can't get module filename");
|
||||
}
|
||||
|
||||
fs::path find_root(bool verbose)
|
||||
{
|
||||
gcx().trace(context::conf, "looking for root directory");
|
||||
|
||||
fs::path mob_exe_dir = mob_exe_path().parent_path();
|
||||
|
||||
auto third_party = mob_exe_dir / "third-party";
|
||||
|
||||
if (!fs::exists(third_party))
|
||||
{
|
||||
if (verbose)
|
||||
u8cout << "no third-party here\n";
|
||||
|
||||
auto p = mob_exe_dir;
|
||||
|
||||
if (p.filename().u8string() == u8"x64")
|
||||
{
|
||||
p = p.parent_path();
|
||||
if (p.filename().u8string() == u8"Debug" ||
|
||||
p.filename().u8string() == u8"Release")
|
||||
{
|
||||
if (verbose)
|
||||
u8cout << "this is mob's build directory, looking up\n";
|
||||
|
||||
// mob_exe_dir is in the build directory
|
||||
third_party = mob_exe_dir / ".." / ".." / ".." / "third-party";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs::exists(third_party))
|
||||
gcx().bail_out(context::conf, "root directory not found");
|
||||
|
||||
const auto p = fs::canonical(third_party.parent_path());
|
||||
gcx().trace(context::conf, "found root directory at {}", p);
|
||||
return p;
|
||||
}
|
||||
|
||||
fs::path find_in_root(const fs::path& file)
|
||||
{
|
||||
static fs::path root = find_root();
|
||||
|
||||
fs::path p = root / file;
|
||||
if (!fs::exists(p))
|
||||
gcx().bail_out(context::conf, "{} not found", p);
|
||||
|
||||
gcx().trace(context::conf, "found {}", p);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
fs::path find_third_party_directory()
|
||||
{
|
||||
static fs::path path = find_in_root("third-party");
|
||||
return path;
|
||||
}
|
||||
|
||||
bool find_qmake(fs::path& check)
|
||||
{
|
||||
// try Qt/Qt5.14.2/msvc*/bin/qmake.exe
|
||||
if (try_parts(check, {
|
||||
"Qt",
|
||||
"Qt" + qt::version(),
|
||||
"msvc" + qt::vs_version() + "_64",
|
||||
"bin",
|
||||
"qmake.exe"}))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// try Qt/5.14.2/msvc*/bin/qmake.exe
|
||||
if (try_parts(check, {
|
||||
"Qt",
|
||||
qt::version(),
|
||||
"msvc" + qt::vs_version() + "_64",
|
||||
"bin",
|
||||
"qmake.exe"}))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool try_qt_location(fs::path& check)
|
||||
{
|
||||
if (!find_qmake(check))
|
||||
return false;
|
||||
|
||||
check = fs::absolute(check.parent_path() / "..");
|
||||
return true;
|
||||
}
|
||||
|
||||
fs::path find_qt()
|
||||
{
|
||||
fs::path p = conf().path().qt_install();
|
||||
|
||||
if (!p.empty())
|
||||
{
|
||||
p = fs::absolute(p);
|
||||
|
||||
if (!try_qt_location(p))
|
||||
gcx().bail_out(context::conf, "no qt install in {}", p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
std::vector<fs::path> locations =
|
||||
{
|
||||
conf().path().pf_x64(),
|
||||
"C:\\",
|
||||
"D:\\"
|
||||
};
|
||||
|
||||
// look for qmake, which is in %qt%/version/msvc.../bin
|
||||
fs::path qmake = find_in_path("qmake.exe");
|
||||
if (!qmake.empty())
|
||||
locations.insert(locations.begin(), qmake.parent_path() / "../../");
|
||||
|
||||
// look for qtcreator.exe, which is in %qt%/Tools/QtCreator/bin
|
||||
fs::path qtcreator = find_in_path("qtcreator.exe");
|
||||
if (!qtcreator.empty())
|
||||
locations.insert(locations.begin(), qtcreator.parent_path() / "../../../");
|
||||
|
||||
for (fs::path loc : locations)
|
||||
{
|
||||
loc = fs::absolute(loc);
|
||||
if (try_qt_location(loc))
|
||||
return loc;
|
||||
}
|
||||
|
||||
gcx().bail_out(context::conf, "can't find qt install");
|
||||
}
|
||||
|
||||
void validate_qt()
|
||||
{
|
||||
fs::path p = qt::installation_path();
|
||||
|
||||
if (!try_qt_location(p))
|
||||
gcx().bail_out(context::conf, "qt path {} doesn't exist", p);
|
||||
|
||||
details::set_string("paths", "qt_install", path_to_utf8(p));
|
||||
}
|
||||
|
||||
fs::path get_known_folder(const GUID& id)
|
||||
{
|
||||
wchar_t* buffer = nullptr;
|
||||
const auto r = ::SHGetKnownFolderPath(id, 0, 0, &buffer);
|
||||
|
||||
if (r != S_OK)
|
||||
return {};
|
||||
|
||||
fs::path p = buffer;
|
||||
::CoTaskMemFree(buffer);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
fs::path find_program_files_x86()
|
||||
{
|
||||
fs::path p = get_known_folder(FOLDERID_ProgramFilesX86);
|
||||
|
||||
if (p.empty())
|
||||
{
|
||||
const auto e = GetLastError();
|
||||
|
||||
p = fs::path(R"(C:\Program Files (x86))");
|
||||
|
||||
gcx().warning(context::conf,
|
||||
"failed to get x86 program files folder, defaulting to {}, {}",
|
||||
p, error_message(e));
|
||||
}
|
||||
else
|
||||
{
|
||||
gcx().trace(context::conf, "x86 program files is {}", p);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
fs::path find_program_files_x64()
|
||||
{
|
||||
fs::path p = get_known_folder(FOLDERID_ProgramFilesX64);
|
||||
|
||||
if (p.empty())
|
||||
{
|
||||
const auto e = GetLastError();
|
||||
|
||||
p = fs::path(R"(C:\Program Files)");
|
||||
|
||||
gcx().warning(context::conf,
|
||||
"failed to get x64 program files folder, defaulting to {}, {}",
|
||||
p, error_message(e));
|
||||
}
|
||||
else
|
||||
{
|
||||
gcx().trace(context::conf, "x64 program files is {}", p);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
fs::path find_temp_dir()
|
||||
{
|
||||
const std::size_t buffer_size = MAX_PATH + 2;
|
||||
wchar_t buffer[buffer_size] = {};
|
||||
|
||||
if (GetTempPathW(static_cast<DWORD>(buffer_size), buffer) == 0)
|
||||
{
|
||||
const auto e = GetLastError();
|
||||
gcx().bail_out(context::conf, "can't get temp path", error_message(e));
|
||||
}
|
||||
|
||||
fs::path p(buffer);
|
||||
gcx().trace(context::conf, "temp dir is {}", p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
fs::path find_vs()
|
||||
{
|
||||
if (conf::dry())
|
||||
return vs::vswhere();
|
||||
|
||||
const auto path = vswhere::find_vs();
|
||||
if (path.empty())
|
||||
gcx().bail_out(context::conf, "vswhere failed");
|
||||
|
||||
const auto lines = split(path_to_utf8(path), "\r\n");
|
||||
|
||||
if (lines.empty())
|
||||
{
|
||||
gcx().bail_out(context::conf, "vswhere didn't output anything");
|
||||
}
|
||||
else if (lines.size() > 1)
|
||||
{
|
||||
gcx().error(context::conf, "vswhere returned multiple installations:");
|
||||
|
||||
for (auto&& line : lines)
|
||||
gcx().error(context::conf, " - {}", line);
|
||||
|
||||
gcx().bail_out(context::conf,
|
||||
"specify the `vs` path in the `[paths]` section of the INI, or "
|
||||
"pass -s paths/vs=PATH` to pick an installation");
|
||||
}
|
||||
|
||||
if (!fs::exists(path))
|
||||
{
|
||||
gcx().bail_out(context::conf,
|
||||
"the path given by vswhere doesn't exist: {}", path);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
bool try_vcvars(fs::path& bat)
|
||||
{
|
||||
if (!fs::exists(bat))
|
||||
return false;
|
||||
|
||||
bat = fs::canonical(fs::absolute(bat));
|
||||
return true;
|
||||
}
|
||||
|
||||
void find_vcvars()
|
||||
{
|
||||
fs::path bat = conf().tool().get("vcvars");
|
||||
|
||||
if (conf::dry())
|
||||
{
|
||||
if (bat.empty())
|
||||
bat = "vcvars.bat";
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bat.empty())
|
||||
{
|
||||
bat = vs::installation_path()
|
||||
/ "VC" / "Auxiliary" / "Build" / "vcvarsall.bat";
|
||||
|
||||
if (!try_vcvars(bat))
|
||||
gcx().bail_out(context::conf, "vcvars not found at {}", bat);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!try_vcvars(bat))
|
||||
gcx().bail_out(context::conf, "vcvars not found at {}", bat);
|
||||
}
|
||||
}
|
||||
|
||||
details::set_string("tools", "vcvars", path_to_utf8(bat));
|
||||
gcx().trace(context::conf, "using vcvars at {}", bat);
|
||||
}
|
||||
|
||||
|
||||
struct parsed_option
|
||||
{
|
||||
std::string task, section, key, value;
|
||||
@@ -929,23 +527,6 @@ void dump_available_options()
|
||||
}
|
||||
|
||||
|
||||
fs::path make_temp_file()
|
||||
{
|
||||
static fs::path dir = conf().path().temp_dir();
|
||||
|
||||
wchar_t name[MAX_PATH + 1] = {};
|
||||
if (GetTempFileNameW(dir.native().c_str(), L"mob", 0, name) == 0)
|
||||
{
|
||||
const auto e = GetLastError();
|
||||
|
||||
gcx().bail_out(context::conf,
|
||||
"can't create temp file in {}, {}", dir, error_message(e));
|
||||
}
|
||||
|
||||
return dir / name;
|
||||
}
|
||||
|
||||
|
||||
conf_global conf::global()
|
||||
{
|
||||
return {};
|
||||
|
||||
@@ -22,10 +22,6 @@ bool verify_options();
|
||||
void log_options();
|
||||
void dump_available_options();
|
||||
|
||||
fs::path find_root(bool verbose=false);
|
||||
fs::path find_in_root(const fs::path& file);
|
||||
fs::path make_temp_file();
|
||||
|
||||
|
||||
template <class DefaultType>
|
||||
class conf_section
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "pch.h"
|
||||
#include "ini.h"
|
||||
#include "paths.h"
|
||||
#include "context.h"
|
||||
#include "env.h"
|
||||
#include "conf.h"
|
||||
|
||||
@@ -0,0 +1,410 @@
|
||||
#include "pch.h"
|
||||
#include "paths.h"
|
||||
#include "../tasks/tasks.h"
|
||||
#include "../utility/string.h"
|
||||
|
||||
namespace mob
|
||||
{
|
||||
|
||||
fs::path find_in_path(std::string_view exe)
|
||||
{
|
||||
const std::wstring wexe = utf8_to_utf16(exe);
|
||||
|
||||
const std::size_t size = MAX_PATH;
|
||||
wchar_t buffer[size + 1] = {};
|
||||
|
||||
if (SearchPathW(nullptr, wexe.c_str(), nullptr, size, buffer, nullptr))
|
||||
return buffer;
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
fs::path find_iscc()
|
||||
{
|
||||
const auto tasks = find_tasks("installer");
|
||||
MOB_ASSERT(tasks.size() == 1);
|
||||
|
||||
if (!tasks[0]->enabled())
|
||||
return {};
|
||||
|
||||
auto iscc = conf().tool().get("iscc");
|
||||
if (iscc.is_absolute())
|
||||
{
|
||||
if (!fs::exists(iscc))
|
||||
{
|
||||
gcx().bail_out(context::conf,
|
||||
"{} doesn't exist (from ini, absolute path)", iscc);
|
||||
}
|
||||
|
||||
return iscc;
|
||||
}
|
||||
|
||||
fs::path p = find_in_path(path_to_utf8(iscc));
|
||||
if (fs::exists(p))
|
||||
return fs::canonical(fs::absolute(p));
|
||||
|
||||
for (int v : {5, 6, 7, 8})
|
||||
{
|
||||
const fs::path inno = fmt::format("inno setup {}", v);
|
||||
|
||||
for (fs::path pf : {conf().path().pf_x86(), conf().path().pf_x64()})
|
||||
{
|
||||
p = pf / inno / iscc;
|
||||
if (fs::exists(p))
|
||||
return fs::canonical(fs::absolute(p));
|
||||
}
|
||||
}
|
||||
|
||||
gcx().bail_out(context::conf, "can't find {} anywhere", iscc);
|
||||
}
|
||||
|
||||
bool try_parts(fs::path& check, const std::vector<std::string>& parts)
|
||||
{
|
||||
for (std::size_t i=0; i<parts.size(); ++i)
|
||||
{
|
||||
fs::path p = check;
|
||||
|
||||
for (std::size_t j=i; j<parts.size(); ++j)
|
||||
p /= parts[j];
|
||||
|
||||
gcx().trace(context::conf, "trying parts {}", p);
|
||||
|
||||
if (fs::exists(p))
|
||||
{
|
||||
check = p;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
fs::path mob_exe_path()
|
||||
{
|
||||
// double the buffer size 10 times
|
||||
const int max_tries = 10;
|
||||
|
||||
DWORD buffer_size = MAX_PATH;
|
||||
|
||||
for (int tries=0; tries<max_tries; ++tries)
|
||||
{
|
||||
auto buffer = std::make_unique<wchar_t[]>(buffer_size + 1);
|
||||
DWORD n = GetModuleFileNameW(0, buffer.get(), buffer_size);
|
||||
|
||||
if (n == 0) {
|
||||
const auto e = GetLastError();
|
||||
gcx().bail_out(context::conf,
|
||||
"can't get module filename, {}", error_message(e));
|
||||
}
|
||||
else if (n >= buffer_size) {
|
||||
// buffer is too small, try again
|
||||
buffer_size *= 2;
|
||||
} else {
|
||||
// if GetModuleFileName() works, `n` does not include the null
|
||||
// terminator
|
||||
const std::wstring s(buffer.get(), n);
|
||||
return fs::canonical(s);
|
||||
}
|
||||
}
|
||||
|
||||
gcx().bail_out(context::conf, "can't get module filename");
|
||||
}
|
||||
|
||||
fs::path find_root(bool verbose)
|
||||
{
|
||||
gcx().trace(context::conf, "looking for root directory");
|
||||
|
||||
fs::path mob_exe_dir = mob_exe_path().parent_path();
|
||||
|
||||
auto third_party = mob_exe_dir / "third-party";
|
||||
|
||||
if (!fs::exists(third_party))
|
||||
{
|
||||
if (verbose)
|
||||
u8cout << "no third-party here\n";
|
||||
|
||||
auto p = mob_exe_dir;
|
||||
|
||||
if (p.filename().u8string() == u8"x64")
|
||||
{
|
||||
p = p.parent_path();
|
||||
if (p.filename().u8string() == u8"Debug" ||
|
||||
p.filename().u8string() == u8"Release")
|
||||
{
|
||||
if (verbose)
|
||||
u8cout << "this is mob's build directory, looking up\n";
|
||||
|
||||
// mob_exe_dir is in the build directory
|
||||
third_party = mob_exe_dir / ".." / ".." / ".." / "third-party";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs::exists(third_party))
|
||||
gcx().bail_out(context::conf, "root directory not found");
|
||||
|
||||
const auto p = fs::canonical(third_party.parent_path());
|
||||
gcx().trace(context::conf, "found root directory at {}", p);
|
||||
return p;
|
||||
}
|
||||
|
||||
fs::path find_in_root(const fs::path& file)
|
||||
{
|
||||
static fs::path root = find_root();
|
||||
|
||||
fs::path p = root / file;
|
||||
if (!fs::exists(p))
|
||||
gcx().bail_out(context::conf, "{} not found", p);
|
||||
|
||||
gcx().trace(context::conf, "found {}", p);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
fs::path find_third_party_directory()
|
||||
{
|
||||
static fs::path path = find_in_root("third-party");
|
||||
return path;
|
||||
}
|
||||
|
||||
bool find_qmake(fs::path& check)
|
||||
{
|
||||
// try Qt/Qt5.14.2/msvc*/bin/qmake.exe
|
||||
if (try_parts(check, {
|
||||
"Qt",
|
||||
"Qt" + qt::version(),
|
||||
"msvc" + qt::vs_version() + "_64",
|
||||
"bin",
|
||||
"qmake.exe"}))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// try Qt/5.14.2/msvc*/bin/qmake.exe
|
||||
if (try_parts(check, {
|
||||
"Qt",
|
||||
qt::version(),
|
||||
"msvc" + qt::vs_version() + "_64",
|
||||
"bin",
|
||||
"qmake.exe"}))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool try_qt_location(fs::path& check)
|
||||
{
|
||||
if (!find_qmake(check))
|
||||
return false;
|
||||
|
||||
check = fs::absolute(check.parent_path() / "..");
|
||||
return true;
|
||||
}
|
||||
|
||||
fs::path find_qt()
|
||||
{
|
||||
fs::path p = conf().path().qt_install();
|
||||
|
||||
if (!p.empty())
|
||||
{
|
||||
p = fs::absolute(p);
|
||||
|
||||
if (!try_qt_location(p))
|
||||
gcx().bail_out(context::conf, "no qt install in {}", p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
std::vector<fs::path> locations =
|
||||
{
|
||||
conf().path().pf_x64(),
|
||||
"C:\\",
|
||||
"D:\\"
|
||||
};
|
||||
|
||||
// look for qmake, which is in %qt%/version/msvc.../bin
|
||||
fs::path qmake = find_in_path("qmake.exe");
|
||||
if (!qmake.empty())
|
||||
locations.insert(locations.begin(), qmake.parent_path() / "../../");
|
||||
|
||||
// look for qtcreator.exe, which is in %qt%/Tools/QtCreator/bin
|
||||
fs::path qtcreator = find_in_path("qtcreator.exe");
|
||||
if (!qtcreator.empty())
|
||||
locations.insert(locations.begin(), qtcreator.parent_path() / "../../../");
|
||||
|
||||
for (fs::path loc : locations)
|
||||
{
|
||||
loc = fs::absolute(loc);
|
||||
if (try_qt_location(loc))
|
||||
return loc;
|
||||
}
|
||||
|
||||
gcx().bail_out(context::conf, "can't find qt install");
|
||||
}
|
||||
|
||||
void validate_qt()
|
||||
{
|
||||
fs::path p = qt::installation_path();
|
||||
|
||||
if (!try_qt_location(p))
|
||||
gcx().bail_out(context::conf, "qt path {} doesn't exist", p);
|
||||
|
||||
details::set_string("paths", "qt_install", path_to_utf8(p));
|
||||
}
|
||||
|
||||
fs::path get_known_folder(const GUID& id)
|
||||
{
|
||||
wchar_t* buffer = nullptr;
|
||||
const auto r = ::SHGetKnownFolderPath(id, 0, 0, &buffer);
|
||||
|
||||
if (r != S_OK)
|
||||
return {};
|
||||
|
||||
fs::path p = buffer;
|
||||
::CoTaskMemFree(buffer);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
fs::path find_program_files_x86()
|
||||
{
|
||||
fs::path p = get_known_folder(FOLDERID_ProgramFilesX86);
|
||||
|
||||
if (p.empty())
|
||||
{
|
||||
const auto e = GetLastError();
|
||||
|
||||
p = fs::path(R"(C:\Program Files (x86))");
|
||||
|
||||
gcx().warning(context::conf,
|
||||
"failed to get x86 program files folder, defaulting to {}, {}",
|
||||
p, error_message(e));
|
||||
}
|
||||
else
|
||||
{
|
||||
gcx().trace(context::conf, "x86 program files is {}", p);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
fs::path find_program_files_x64()
|
||||
{
|
||||
fs::path p = get_known_folder(FOLDERID_ProgramFilesX64);
|
||||
|
||||
if (p.empty())
|
||||
{
|
||||
const auto e = GetLastError();
|
||||
|
||||
p = fs::path(R"(C:\Program Files)");
|
||||
|
||||
gcx().warning(context::conf,
|
||||
"failed to get x64 program files folder, defaulting to {}, {}",
|
||||
p, error_message(e));
|
||||
}
|
||||
else
|
||||
{
|
||||
gcx().trace(context::conf, "x64 program files is {}", p);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
fs::path find_temp_dir()
|
||||
{
|
||||
const std::size_t buffer_size = MAX_PATH + 2;
|
||||
wchar_t buffer[buffer_size] = {};
|
||||
|
||||
if (GetTempPathW(static_cast<DWORD>(buffer_size), buffer) == 0)
|
||||
{
|
||||
const auto e = GetLastError();
|
||||
gcx().bail_out(context::conf, "can't get temp path", error_message(e));
|
||||
}
|
||||
|
||||
fs::path p(buffer);
|
||||
gcx().trace(context::conf, "temp dir is {}", p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
fs::path find_vs()
|
||||
{
|
||||
if (conf::dry())
|
||||
return vs::vswhere();
|
||||
|
||||
const auto path = vswhere::find_vs();
|
||||
if (path.empty())
|
||||
gcx().bail_out(context::conf, "vswhere failed");
|
||||
|
||||
const auto lines = split(path_to_utf8(path), "\r\n");
|
||||
|
||||
if (lines.empty())
|
||||
{
|
||||
gcx().bail_out(context::conf, "vswhere didn't output anything");
|
||||
}
|
||||
else if (lines.size() > 1)
|
||||
{
|
||||
gcx().error(context::conf, "vswhere returned multiple installations:");
|
||||
|
||||
for (auto&& line : lines)
|
||||
gcx().error(context::conf, " - {}", line);
|
||||
|
||||
gcx().bail_out(context::conf,
|
||||
"specify the `vs` path in the `[paths]` section of the INI, or "
|
||||
"pass -s paths/vs=PATH` to pick an installation");
|
||||
}
|
||||
|
||||
if (!fs::exists(path))
|
||||
{
|
||||
gcx().bail_out(context::conf,
|
||||
"the path given by vswhere doesn't exist: {}", path);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
bool try_vcvars(fs::path& bat)
|
||||
{
|
||||
if (!fs::exists(bat))
|
||||
return false;
|
||||
|
||||
bat = fs::canonical(fs::absolute(bat));
|
||||
return true;
|
||||
}
|
||||
|
||||
void find_vcvars()
|
||||
{
|
||||
fs::path bat = conf().tool().get("vcvars");
|
||||
|
||||
if (conf::dry())
|
||||
{
|
||||
if (bat.empty())
|
||||
bat = "vcvars.bat";
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bat.empty())
|
||||
{
|
||||
bat = vs::installation_path()
|
||||
/ "VC" / "Auxiliary" / "Build" / "vcvarsall.bat";
|
||||
|
||||
if (!try_vcvars(bat))
|
||||
gcx().bail_out(context::conf, "vcvars not found at {}", bat);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!try_vcvars(bat))
|
||||
gcx().bail_out(context::conf, "vcvars not found at {}", bat);
|
||||
}
|
||||
}
|
||||
|
||||
details::set_string("tools", "vcvars", path_to_utf8(bat));
|
||||
gcx().trace(context::conf, "using vcvars at {}", bat);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
namespace mob
|
||||
{
|
||||
|
||||
fs::path find_root(bool verbose=false);
|
||||
fs::path find_in_root(const fs::path& file);
|
||||
|
||||
fs::path find_third_party_directory();
|
||||
fs::path find_program_files_x86();
|
||||
fs::path find_program_files_x64();
|
||||
fs::path find_vs();
|
||||
fs::path find_qt();
|
||||
fs::path find_iscc();
|
||||
fs::path find_temp_dir();
|
||||
|
||||
void find_vcvars();
|
||||
void validate_qt();
|
||||
|
||||
fs::path mob_exe_path();
|
||||
|
||||
} // namespace
|
||||
@@ -8,6 +8,23 @@
|
||||
namespace mob
|
||||
{
|
||||
|
||||
fs::path make_temp_file()
|
||||
{
|
||||
static fs::path dir = conf().path().temp_dir();
|
||||
|
||||
wchar_t name[MAX_PATH + 1] = {};
|
||||
if (GetTempFileNameW(dir.native().c_str(), L"mob", 0, name) == 0)
|
||||
{
|
||||
const auto e = GetLastError();
|
||||
|
||||
gcx().bail_out(context::conf,
|
||||
"can't create temp file in {}, {}", dir, error_message(e));
|
||||
}
|
||||
|
||||
return dir / name;
|
||||
}
|
||||
|
||||
|
||||
file_deleter::file_deleter(const context& cx, fs::path p)
|
||||
: cx_(cx), p_(std::move(p)), delete_(true)
|
||||
{
|
||||
|
||||
@@ -6,6 +6,11 @@ namespace mob
|
||||
class context;
|
||||
|
||||
|
||||
// returns a unique filename in the temp directory; requires inis to be loaded
|
||||
//
|
||||
fs::path make_temp_file();
|
||||
|
||||
|
||||
struct handle_closer
|
||||
{
|
||||
using pointer = HANDLE;
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
<ClCompile Include="..\src\core\env.cpp" />
|
||||
<ClCompile Include="..\src\core\ini.cpp" />
|
||||
<ClCompile Include="..\src\core\op.cpp" />
|
||||
<ClCompile Include="..\src\core\paths.cpp" />
|
||||
<ClCompile Include="..\src\core\pipe.cpp" />
|
||||
<ClCompile Include="..\src\core\process.cpp" />
|
||||
<ClCompile Include="..\src\main.cpp" />
|
||||
@@ -128,6 +129,7 @@
|
||||
<ClInclude Include="..\src\core\env.h" />
|
||||
<ClInclude Include="..\src\core\ini.h" />
|
||||
<ClInclude Include="..\src\core\op.h" />
|
||||
<ClInclude Include="..\src\core\paths.h" />
|
||||
<ClInclude Include="..\src\core\pipe.h" />
|
||||
<ClInclude Include="..\src\core\process.h" />
|
||||
<ClInclude Include="..\src\net.h" />
|
||||
|
||||
@@ -198,6 +198,9 @@
|
||||
<ClCompile Include="..\src\core\ini.cpp">
|
||||
<Filter>src\core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\core\paths.cpp">
|
||||
<Filter>src\core</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\pch.h">
|
||||
@@ -263,5 +266,8 @@
|
||||
<ClInclude Include="..\src\core\ini.h">
|
||||
<Filter>src\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\core\paths.h">
|
||||
<Filter>src\core</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user