@@ -56,6 +56,36 @@ namespace vix::commands::RunCommand::detail
5656 Manifest
5757 };
5858
59+ /* *
60+ * @brief Execution strategy selected for a single C++ script.
61+ *
62+ * Direct means a fast compile-and-run path without generated CMake.
63+ * CMakeFallback means the legacy generated CMake project pipeline.
64+ */
65+ enum class ScriptExecutionStrategy
66+ {
67+ None,
68+ Direct,
69+ CMakeFallback
70+ };
71+
72+ /* *
73+ * @brief Coarse reason explaining why a script cannot use direct compilation.
74+ */
75+ enum class ScriptFallbackReason
76+ {
77+ None,
78+ UsesCompiledDeps,
79+ UsesVixRuntime,
80+ UsesOrm,
81+ UsesDatabase,
82+ UsesMySql,
83+ RequiresCMakeTargets,
84+ UnsupportedFlags,
85+ UnsupportedLayout,
86+ Unknown
87+ };
88+
5989 /* *
6090 * @brief Parsing state and user-facing options for `vix run`.
6191 *
@@ -180,6 +210,139 @@ namespace vix::commands::RunCommand::detail
180210 std::string runCmd;
181211 };
182212
213+ /* *
214+ * @brief Parsed compile-related flags extracted from script mode arguments.
215+ */
216+ struct ScriptCompileFlags
217+ {
218+ std::vector<std::string> includeDirs;
219+ std::vector<std::string> systemIncludeDirs;
220+ std::vector<std::string> defines;
221+ std::vector<std::string> compileOpts;
222+ };
223+
224+ /* *
225+ * @brief Parsed link-related flags extracted from script mode arguments.
226+ */
227+ struct ScriptLinkFlags
228+ {
229+ std::vector<std::string> libs;
230+ std::vector<std::string> libDirs;
231+ std::vector<std::string> linkOpts;
232+ };
233+
234+ /* *
235+ * @brief High-level feature detection result for a C++ script.
236+ */
237+ struct ScriptFeatures
238+ {
239+ bool usesVix = false ;
240+ bool usesOrm = false ;
241+ bool usesDb = false ;
242+ bool usesMySql = false ;
243+ };
244+
245+ /* *
246+ * @brief Result of probing a script before choosing the execution engine.
247+ *
248+ * This structure gathers the information needed to decide whether the script
249+ * can be compiled directly or should fall back to the generated CMake path.
250+ */
251+ struct ScriptProbeResult
252+ {
253+ ScriptExecutionStrategy strategy = ScriptExecutionStrategy::None;
254+ ScriptFallbackReason fallbackReason = ScriptFallbackReason::None;
255+
256+ bool canUseDirectCompile = false ;
257+ bool shouldUseCMakeFallback = true ;
258+
259+ bool usesVixRuntime = false ;
260+ bool usesCompiledDeps = false ;
261+ bool requiresCMakeTargets = false ;
262+
263+ ScriptFeatures features;
264+ ScriptCompileFlags compileFlags;
265+ ScriptLinkFlags linkFlags;
266+
267+ std::vector<std::string> includeDirs;
268+ std::vector<std::string> systemIncludeDirs;
269+ std::vector<std::string> defines;
270+ std::vector<std::string> compileOpts;
271+ std::vector<std::string> libDirs;
272+ std::vector<std::string> libs;
273+ std::vector<std::string> linkOpts;
274+
275+ std::vector<std::string> orderedDepIds;
276+ std::vector<fs::path> compiledDepPaths;
277+ std::vector<fs::path> headerOnlyDepIncludeDirs;
278+ };
279+
280+ /* *
281+ * @brief Cache metadata for a directly compiled script artifact.
282+ */
283+ struct DirectScriptCacheState
284+ {
285+ fs::path rootDir;
286+ fs::path binaryPath;
287+ fs::path metaFile;
288+ fs::path stdoutLogPath;
289+ fs::path stderrLogPath;
290+
291+ std::string cacheKey;
292+ bool cacheHit = false ;
293+ bool needsRebuild = true ;
294+ };
295+
296+ /* *
297+ * @brief Concrete plan for the fast direct-compile script path.
298+ */
299+ struct DirectScriptPlan
300+ {
301+ fs::path scriptPath;
302+ fs::path workingDir;
303+ fs::path binaryPath;
304+ fs::path cacheDir;
305+
306+ std::string exeName;
307+ std::string cacheKey;
308+ std::string compileCmd;
309+ std::string runCmd;
310+
311+ bool shouldCompile = true ;
312+ bool shouldRun = true ;
313+ bool passthroughRuntime = false ;
314+ int effectiveTimeoutSec = 0 ;
315+
316+ ScriptProbeResult probe;
317+ };
318+
319+ /* *
320+ * @brief Concrete plan for the generated CMake fallback path.
321+ */
322+ struct CMakeScriptPlan
323+ {
324+ fs::path scriptPath;
325+ fs::path scriptsRoot;
326+ fs::path projectDir;
327+ fs::path cmakeListsPath;
328+ fs::path buildDir;
329+ fs::path exePath;
330+ fs::path signatureFile;
331+ fs::path configureLogPath;
332+ fs::path buildLogPath;
333+
334+ std::string exeName;
335+ std::string targetName;
336+ std::string configSignature;
337+
338+ bool useVixRuntime = false ;
339+ bool shouldConfigure = true ;
340+ bool shouldBuild = true ;
341+ bool shouldRun = true ;
342+ bool passthroughRuntime = false ;
343+ int effectiveTimeoutSec = 0 ;
344+ };
345+
183346 /* *
184347 * @brief Result returned by script-mode execution helpers.
185348 */
@@ -349,21 +512,125 @@ namespace vix::commands::RunCommand::detail
349512 bool alreadyHandled);
350513
351514 // ===========================================================================
352- // Script mode
515+ // Script probing / planning
353516 // ===========================================================================
354517
355518 /* *
356- * @brief Return the root directory used for generated script projects .
519+ * @brief Detect whether a .cpp script uses the Vix runtime .
357520 */
358- fs::path get_scripts_root ( bool localCache );
521+ bool script_uses_vix ( const fs::path &cppPath );
359522
360523 /* *
361- * @brief Detect whether a .cpp script uses the Vix runtime .
524+ * @brief Detect high-level features used by a C++ script .
362525 */
363- bool script_uses_vix (const fs::path &cppPath);
526+ ScriptFeatures detect_script_features (const fs::path &cppPath);
527+
528+ /* *
529+ * @brief Parse compile flags from script-mode forwarded arguments.
530+ */
531+ ScriptCompileFlags parse_compile_flags (const std::vector<std::string> &flags);
532+
533+ /* *
534+ * @brief Parse link flags from script-mode forwarded arguments.
535+ */
536+ ScriptLinkFlags parse_link_flags (const std::vector<std::string> &flags);
537+
538+ /* *
539+ * @brief Probe a single C++ script and choose the execution strategy.
540+ */
541+ ScriptProbeResult probe_single_cpp_script (const Options &opt);
542+
543+ /* *
544+ * @brief Return true when the probed script can use direct compilation.
545+ *
546+ * The direct path is intentionally strict. It is reserved for simple,
547+ * single-file, header-only friendly scripts that do not require runtime
548+ * targets, compiled dependencies, or custom link steps.
549+ */
550+ inline bool script_can_use_direct_compile (const ScriptProbeResult &probe) noexcept
551+ {
552+ if (!probe.canUseDirectCompile )
553+ return false ;
554+
555+ if (probe.strategy != ScriptExecutionStrategy::Direct)
556+ return false ;
557+
558+ if (probe.usesVixRuntime )
559+ return false ;
560+
561+ if (probe.usesCompiledDeps )
562+ return false ;
563+
564+ if (probe.requiresCMakeTargets )
565+ return false ;
566+
567+ if (!probe.libs .empty ())
568+ return false ;
569+
570+ if (!probe.libDirs .empty ())
571+ return false ;
572+
573+ if (!probe.linkOpts .empty ())
574+ return false ;
575+
576+ if (!probe.compiledDepPaths .empty ())
577+ return false ;
578+
579+ return true ;
580+ }
581+
582+ /* *
583+ * @brief Return true when the probed script should use generated CMake fallback.
584+ */
585+ inline bool script_needs_cmake_fallback (const ScriptProbeResult &probe) noexcept
586+ {
587+ return probe.shouldUseCMakeFallback ||
588+ probe.strategy == ScriptExecutionStrategy::CMakeFallback;
589+ }
364590
365591 /* *
366- * @brief Generate the CMakeLists.txt content used by script mode.
592+ * @brief Build the fast direct-compile plan for a probed script.
593+ */
594+ DirectScriptPlan make_direct_script_plan (
595+ const Options &opt,
596+ const ScriptProbeResult &probe);
597+
598+ /* *
599+ * @brief Build the generated CMake fallback plan for a probed script.
600+ */
601+ CMakeScriptPlan make_cmake_script_plan (
602+ const Options &opt,
603+ const ScriptProbeResult &probe);
604+
605+ /* *
606+ * @brief Compute the global cache root used for directly compiled scripts.
607+ */
608+ fs::path get_direct_scripts_cache_root ();
609+
610+ /* *
611+ * @brief Compute the cache key used for a directly compiled script.
612+ */
613+ std::string make_direct_script_cache_key (
614+ const fs::path &cppPath,
615+ const ScriptProbeResult &probe,
616+ const Options &opt);
617+
618+ /* *
619+ * @brief Load the cache state for a directly compiled script plan.
620+ */
621+ DirectScriptCacheState load_direct_script_cache_state (const DirectScriptPlan &plan);
622+
623+ // ===========================================================================
624+ // Script mode execution
625+ // ===========================================================================
626+
627+ /* *
628+ * @brief Return the root directory used for generated script projects.
629+ */
630+ fs::path get_scripts_root (bool localCache);
631+
632+ /* *
633+ * @brief Generate the CMakeLists.txt content used by script fallback mode.
367634 */
368635 std::string make_script_cmakelists (
369636 const std::string &exeName,
@@ -374,10 +641,23 @@ namespace vix::commands::RunCommand::detail
374641 bool withMySql);
375642
376643 /* *
377- * @brief Execute a single C++ file with the script pipeline.
644+ * @brief Execute a single C++ file using the best available script engine.
645+ *
646+ * This dispatcher probes the script first, then selects either the direct
647+ * compile path or the generated CMake fallback path.
378648 */
379649 int run_single_cpp (const Options &opt);
380650
651+ /* *
652+ * @brief Execute a single C++ file with the fast direct-compile engine.
653+ */
654+ int run_single_cpp_direct (const Options &opt, const DirectScriptPlan &plan);
655+
656+ /* *
657+ * @brief Execute a single C++ file with the generated CMake fallback engine.
658+ */
659+ int run_single_cpp_cmake (const Options &opt, const CMakeScriptPlan &plan);
660+
381661 /* *
382662 * @brief Execute a single C++ file in watch mode.
383663 */
0 commit comments