55 external_install_path() = path;
56 return inspect_install_path(path,
"user-provided MARTY path");
64 external_install_path().reset();
72 if (external_install_path().has_value()) {
73 return inspect_install_path(*external_install_path(),
"user-provided MARTY path");
89 LOG_DEBUG(
"MARTY runtime resolved for", context,
":", info.prefix.string());
95 "MARTY mode requested in", context,
96 "but no valid MARTY installation could be resolved.",
98 "Call HyperisoMaster::pre_init_set_marty_path(<MARTY_INSTALL>) before init(),",
99 "or build/install the bundled MARTY with -DBUILD_WITH_MARTY=ON."
109 std::string raw = path.string();
110 std::string quoted =
"'";
124 return std::filesystem::path(project_tp_root.data()) /
"MARTY" /
"MARTY_INSTALL";
129 return external_install_path().has_value();
133 static std::optional<std::filesystem::path>& external_install_path()
135 static std::optional<std::filesystem::path> path;
139 static std::string default_source_label()
141#ifdef BUILD_WITH_MARTY
142 return "bundled MARTY install from BUILD_WITH_MARTY";
144 return "default bundled MARTY install path";
148 static bool is_marty_library_name(
const std::filesystem::path& path)
150 const auto filename = path.filename().string();
151 return filename ==
"libmarty.so"
152 || filename ==
"libmarty.dylib"
153 || filename ==
"libmarty.a";
156 static std::optional<std::filesystem::path> find_marty_library(
const std::filesystem::path& lib_dir)
158 const std::vector<std::string> names = {
164 for (
const auto& name : names) {
165 std::filesystem::path candidate = lib_dir /
name;
166 if (std::filesystem::exists(candidate)) {
173 static std::filesystem::path normalize_prefix_candidate(
const std::filesystem::path& requested)
175 if (requested.empty()) {
179 std::filesystem::path p = std::filesystem::absolute(requested).lexically_normal();
181 if (std::filesystem::is_regular_file(p)) {
182 if (p.filename() ==
"marty.h") {
183 return p.parent_path().parent_path();
185 if (is_marty_library_name(p)) {
186 return p.parent_path().parent_path();
190 if (p.filename() ==
"include" && std::filesystem::exists(p /
"marty.h")) {
191 return p.parent_path();
194 if (p.filename() ==
"lib" && find_marty_library(p).has_value()) {
195 return p.parent_path();
198 if (std::filesystem::exists(p /
"include" /
"marty.h")) {
202 if (std::filesystem::exists(p /
"MARTY_INSTALL" /
"include" /
"marty.h")) {
203 return p /
"MARTY_INSTALL";
206 if (std::filesystem::exists(p /
"install" /
"include" /
"marty.h")) {
207 return p /
"install";
213 static InstallInfo inspect_install_path(
const std::filesystem::path& requested, std::string source)
216 info.requested_path = requested;
217 info.source = std::move(source);
218 info.prefix = normalize_prefix_candidate(requested);
219 info.include_dir = info.prefix /
"include";
220 info.lib_dir = info.prefix /
"lib";
221 info.marty_header = info.include_dir /
"marty.h";
222 info.marty_executable = info.prefix /
"bin" /
"marty";
224 std::vector<std::string> errors;
226 if (requested.empty()) {
227 errors.emplace_back(
"empty path");
230 if (!std::filesystem::exists(info.prefix)) {
231 errors.emplace_back(
"prefix does not exist: " + info.prefix.string());
234 if (!std::filesystem::exists(info.marty_header)) {
235 errors.emplace_back(
"missing header: " + info.marty_header.string());
238 auto lib = find_marty_library(info.lib_dir);
239 if (!lib.has_value()) {
240 errors.emplace_back(
"missing libmarty in: " + info.lib_dir.string());
242 info.marty_library = *lib;
245 info.has_executable = std::filesystem::exists(info.marty_executable)
246 && !std::filesystem::is_directory(info.marty_executable);
248 info.valid = errors.empty();
250 std::ostringstream oss;
251 oss <<
"Checked " << info.source <<
" at " << requested.string() <<
". ";
252 for (
size_t i = 0; i < errors.size(); ++i) {
256 oss << errors[i] <<
".";
258 info.error = oss.str();