Skip to content

Commit d28fa01

Browse files
committed
perf(cli): cache single-file Vix builds
1 parent d9b40a6 commit d28fa01

8 files changed

Lines changed: 704 additions & 41 deletions

File tree

‎include/vix/cli/commands/run/RunDetail.hpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ namespace vix::commands::RunCommand::detail
296296
fs::path stderrLogPath;
297297

298298
std::string cacheKey;
299+
std::string rebuildReason;
299300
bool cacheHit = false;
300301
bool needsRebuild = true;
301302
};
@@ -713,6 +714,11 @@ namespace vix::commands::RunCommand::detail
713714
*/
714715
DirectScriptCacheState load_direct_script_cache_state(const DirectScriptPlan &plan);
715716

717+
/**
718+
* @brief Persist positive direct script cache metadata after a successful compile.
719+
*/
720+
bool persist_direct_script_cache_metadata(const DirectScriptPlan &plan);
721+
716722
// ===========================================================================
717723
// Script mode execution
718724
// ===========================================================================

‎include/vix/cli/commands/run/detail/DirectScriptRunner.hpp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ namespace vix::commands::RunCommand::detail
4141
*/
4242
DirectScriptCacheState load_direct_script_cache_state(const DirectScriptPlan &plan);
4343

44+
/**
45+
* @brief Persist positive direct script cache metadata after a successful compile.
46+
*/
47+
bool persist_direct_script_cache_metadata(const DirectScriptPlan &plan);
48+
4449
/**
4550
* @brief Build a direct compile plan for a probed script.
4651
*/

‎src/commands/run/RunScript.cpp‎

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,54 @@ namespace vix::commands::RunCommand::detail
14411441
return ensure_script_executable_exists(state);
14421442
}
14431443

1444+
const char *script_fallback_reason_name(ScriptFallbackReason reason) noexcept
1445+
{
1446+
switch (reason)
1447+
{
1448+
case ScriptFallbackReason::None:
1449+
return "none";
1450+
case ScriptFallbackReason::UsesCompiledDeps:
1451+
return "uses compiled dependencies";
1452+
case ScriptFallbackReason::UsesVixRuntime:
1453+
return "uses Vix runtime without direct installation";
1454+
case ScriptFallbackReason::UsesOrm:
1455+
return "uses ORM";
1456+
case ScriptFallbackReason::UsesDatabase:
1457+
return "uses database";
1458+
case ScriptFallbackReason::UsesMySql:
1459+
return "uses MySQL";
1460+
case ScriptFallbackReason::RequiresCMakeTargets:
1461+
return "requires CMake targets";
1462+
case ScriptFallbackReason::UnsupportedFlags:
1463+
return "unsupported compiler flags";
1464+
case ScriptFallbackReason::UnsupportedLayout:
1465+
return "unsupported layout";
1466+
case ScriptFallbackReason::Unknown:
1467+
return "unknown";
1468+
}
1469+
1470+
return "unknown";
1471+
}
1472+
1473+
bool trace_script_strategy_enabled(const Options &opt)
1474+
{
1475+
if (opt.verbose)
1476+
return true;
1477+
1478+
const char *env = vix::utils::vix_getenv("VIX_RUN_TRACE_CACHE");
1479+
return env && *env && std::string(env) != "0";
1480+
}
1481+
1482+
void print_cmake_fallback_trace(const Options &opt, const ScriptProbeResult &probe)
1483+
{
1484+
if (!trace_script_strategy_enabled(opt))
1485+
return;
1486+
1487+
std::cerr << "script strategy: cmake fallback\n";
1488+
std::cerr << "fallback reason: "
1489+
<< script_fallback_reason_name(probe.fallbackReason) << "\n";
1490+
}
1491+
14441492
int build_script_executable_internal(const Options &opt, fs::path &exePath)
14451493
{
14461494
Options o = opt;
@@ -1472,7 +1520,7 @@ namespace vix::commands::RunCommand::detail
14721520

14731521
const DirectScriptCacheState cache = load_direct_script_cache_state(directPlan);
14741522

1475-
if (directPlan.shouldCompile)
1523+
if (cache.needsRebuild)
14761524
{
14771525
const LiveRunResult build = run_cmd_live_filtered_capture(
14781526
directPlan.compileCmd,
@@ -1501,14 +1549,15 @@ namespace vix::commands::RunCommand::detail
15011549
return build.exitCode != 0 ? build.exitCode : 1;
15021550
}
15031551

1504-
// Do not rewrite legacy cache metadata here.
1505-
// The direct runner owns the cache metadata format.
1552+
if (!persist_direct_script_cache_metadata(directPlan))
1553+
std::cerr << "warning: unable to persist direct script cache metadata\n";
15061554
}
15071555

15081556
exePath = directPlan.binaryPath;
15091557
return 0;
15101558
}
15111559

1560+
print_cmake_fallback_trace(o, probe);
15121561
const CMakeScriptPlan cmakePlan = make_cmake_script_plan(o, probe);
15131562
ScriptProjectState state = make_state_from_cmake_plan(cmakePlan);
15141563

@@ -1647,6 +1696,7 @@ namespace vix::commands::RunCommand::detail
16471696
return run_single_cpp_direct(o, directPlan);
16481697
}
16491698

1699+
print_cmake_fallback_trace(o, probe);
16501700
const CMakeScriptPlan cmakePlan = make_cmake_script_plan(o, probe);
16511701
return run_single_cpp_cmake(o, cmakePlan);
16521702
}

‎src/commands/run/RunScriptHelpers.cpp‎

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,13 +299,29 @@ namespace vix::commands::RunCommand::detail
299299

300300
std::optional<fs::path> find_vix_lib()
301301
{
302+
std::vector<fs::path> prefixes;
303+
304+
const char *home = vix::utils::vix_getenv(
305+
#ifdef _WIN32
306+
"USERPROFILE"
307+
#else
308+
"HOME"
309+
#endif
310+
);
311+
312+
if (home && *home)
313+
prefixes.push_back(fs::path(home) / ".vix" / "lib");
314+
315+
prefixes.emplace_back("/usr/local/lib");
316+
prefixes.emplace_back("/usr/lib");
317+
302318
std::error_code ec;
303319

304-
for (const char *prefix : {"/usr/local/lib", "/usr/lib"})
320+
for (const auto &prefix : prefixes)
305321
{
306322
for (const char *name : {"libvix.a", "libvix.so", "libvix.dylib"})
307323
{
308-
const fs::path p = fs::path(prefix) / name;
324+
const fs::path p = prefix / name;
309325
ec.clear();
310326
if (fs::exists(p, ec) && !ec)
311327
return p;
@@ -318,8 +334,23 @@ namespace vix::commands::RunCommand::detail
318334
std::vector<fs::path> find_vix_all_module_libs()
319335
{
320336
std::vector<fs::path> result;
337+
std::vector<fs::path> prefixes;
321338
std::error_code ec;
322339

340+
const char *home = vix::utils::vix_getenv(
341+
#ifdef _WIN32
342+
"USERPROFILE"
343+
#else
344+
"HOME"
345+
#endif
346+
);
347+
348+
if (home && *home)
349+
prefixes.push_back(fs::path(home) / ".vix" / "lib");
350+
351+
prefixes.emplace_back("/usr/local/lib");
352+
prefixes.emplace_back("/usr/lib");
353+
323354
static const char *modules[] = {
324355
"libvix_core.a",
325356
"libvix_net.a",
@@ -344,14 +375,14 @@ namespace vix::commands::RunCommand::detail
344375
"libvix_error.a",
345376
nullptr};
346377

347-
for (const char *prefix : {"/usr/local/lib", "/usr/lib"})
378+
for (const auto &prefix : prefixes)
348379
{
349380
bool found = false;
350381
std::vector<fs::path> batch;
351382

352383
for (int i = 0; modules[i] != nullptr; ++i)
353384
{
354-
const fs::path p = fs::path(prefix) / modules[i];
385+
const fs::path p = prefix / modules[i];
355386
ec.clear();
356387
if (fs::exists(p, ec) && !ec)
357388
{

0 commit comments

Comments
 (0)