3535#endif
3636
3737// forward declarations
38+ #ifndef _WIN32
3839static gchar * _get_rocm_version (void );
40+ #endif
41+ static gchar * _get_cuda_version (void );
3942
4043// ---------------------------------------------------------------------------
4144// Manifest-driven package metadata (loaded from data/ort_gpu.json)
@@ -186,32 +189,17 @@ static _ort_package_t *_find_package(GList *packages, dt_ort_gpu_vendor_t vendor
186189#endif
187190
188191 gchar * rocm_mm = NULL ;
192+ #ifndef _WIN32
189193 if (vendor == DT_ORT_GPU_AMD )
190194 {
191195 gchar * rocm_ver = _get_rocm_version ();
192196 rocm_mm = _version_major_minor (rocm_ver );
193197 g_free (rocm_ver );
194198 }
199+ #endif
195200
196- // detect CUDA toolkit version via nvcc
197- gchar * cuda_mm = NULL ;
198- if (vendor == DT_ORT_GPU_NVIDIA )
199- {
200- gchar * nvcc_out = NULL ;
201- if (g_spawn_command_line_sync ("nvcc --version" , & nvcc_out ,
202- NULL , NULL , NULL )
203- && nvcc_out )
204- {
205- // parse "Cuda compilation tools, release X.Y, VX.Y.Z"
206- gchar * v = g_strstr_len (nvcc_out , -1 , ", V" );
207- if (v )
208- {
209- v += 3 ; // skip ", V"
210- cuda_mm = _version_major_minor (v );
211- }
212- g_free (nvcc_out );
213- }
214- }
201+ // detect CUDA toolkit version (nvcc on Linux, CUDA_PATH on Windows)
202+ gchar * cuda_mm = (vendor == DT_ORT_GPU_NVIDIA ) ? _get_cuda_version () : NULL ;
215203
216204 _ort_package_t * best = NULL ;
217205 for (GList * l = packages ; l ; l = g_list_next (l ))
@@ -246,18 +234,14 @@ static _ort_package_t *_find_package(GList *packages, dt_ort_gpu_vendor_t vendor
246234// Helpers
247235// ---------------------------------------------------------------------------
248236
249- // run a command via shell and capture stdout. Returns TRUE on success
250- // on Linux uses sh -c to support pipes and redirections
251- // on Windows uses cmd /c since /bin/sh is not available
237+ #ifndef _WIN32
238+ // run a command via sh -c and capture stdout. Use for commands that
239+ // need shell features like pipes or redirections.
252240static gboolean _run_cmd (const char * cmd , char * * out )
253241{
254242 gchar * stdout_buf = NULL ;
255243 gint exit_status = 0 ;
256- #ifdef _WIN32
257- const gchar * argv [] = { "cmd.exe" , "/c" , cmd , NULL };
258- #else
259244 const gchar * argv [] = { "/bin/sh" , "-c" , cmd , NULL };
260- #endif
261245 gboolean ok = g_spawn_sync (NULL , (gchar * * )argv , NULL ,
262246 G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL ,
263247 NULL , NULL , & stdout_buf , NULL , & exit_status , NULL );
@@ -272,10 +256,11 @@ static gboolean _run_cmd(const char *cmd, char **out)
272256 if (out ) * out = NULL ;
273257 return FALSE;
274258}
259+ #endif
275260
261+ #ifndef _WIN32
276262// run a command directly (no shell) and capture stdout. Use this for
277- // commands that don't need shell features — avoids cmd.exe quoting
278- // issues and console-window flicker on Windows GUI apps
263+ // commands that don't need shell features
279264static gboolean _run_argv (const gchar * const * argv , char * * out )
280265{
281266 gchar * stdout_buf = NULL ;
@@ -294,6 +279,7 @@ static gboolean _run_argv(const gchar * const *argv, char **out)
294279 if (out ) * out = NULL ;
295280 return FALSE;
296281}
282+ #endif
297283
298284#ifdef _WIN32
299285// recursively search a directory for a file whose name starts with prefix.
@@ -319,6 +305,7 @@ static gboolean _find_file_recursive(const char *dir, const char *prefix)
319305}
320306#endif
321307
308+ #ifndef _WIN32
322309// check if a library is in /etc/ld.so.cache — fast but only works
323310// when the distro package registered a SONAME (Debian's libcudnn9
324311// package does not, so this misses cuDNN there)
@@ -377,16 +364,28 @@ static gchar *_get_rocm_version(void)
377364 }
378365 return NULL ;
379366}
367+ #endif // !_WIN32
380368
381369
382370// ---------------------------------------------------------------------------
383371// GPU detection
384372// ---------------------------------------------------------------------------
385373
386- // Get CUDA toolkit version (major.minor) from nvcc, e.g. "13.2".
387- // Returns NULL if nvcc is not available.
374+ // Get CUDA toolkit version (major.minor), e.g. "13.2".
375+ // On Windows: parse CUDA_PATH (e.g. ".../CUDA/v13.2"), which is set by
376+ // the CUDA installer and is always present regardless of PATH.
377+ // On Linux: run nvcc --version. Returns NULL if not found.
388378static gchar * _get_cuda_version (void )
389379{
380+ #ifdef _WIN32
381+ const char * cuda_path = g_getenv ("CUDA_PATH" );
382+ if (!cuda_path ) return NULL ;
383+ const char * sep = strrchr (cuda_path , '\\' );
384+ if (!sep ) sep = strrchr (cuda_path , '/' );
385+ const char * ver = sep ? sep + 1 : cuda_path ;
386+ if (ver [0 ] == 'v' || ver [0 ] == 'V' ) ver ++ ;
387+ return _version_major_minor (ver );
388+ #else
390389 gchar * nvcc_out = NULL ;
391390 if (!g_spawn_command_line_sync ("nvcc --version" , & nvcc_out , NULL , NULL , NULL )
392391 || !nvcc_out )
@@ -397,6 +396,7 @@ static gchar *_get_cuda_version(void)
397396 result = _version_major_minor (v + 3 ); // skip ", V"
398397 g_free (nvcc_out );
399398 return result ;
399+ #endif
400400}
401401
402402static dt_ort_gpu_info_t * _detect_nvidia (void )
0 commit comments