@@ -3017,6 +3017,33 @@ const TString& TROOT::GetBinDir() {
30173017// //////////////////////////////////////////////////////////////////////////////
30183018// / Get the library directory in the installation. Static utility function.
30193019// /
3020+ // / By default, this is just an alias for TROOT::GetSharedLibDir(), which
3021+ // / returns the directory containing the ROOT shared libraries.
3022+ // /
3023+ // / On Windows, the behavior is different. In that case, this function doesn't
3024+ // / return the directory of the **shared libraries** (like `libCore.dll`), but
3025+ // / the **import libraries**, which are used at link time (like `libCore.lib`).
3026+
3027+ const TString &TROOT::GetLibDir ()
3028+ {
3029+ #if defined(R__WIN32)
3030+ static bool initialized = false ;
3031+ static TString rootlibdir;
3032+ if (initialized)
3033+ return rootlibdir;
3034+
3035+ initialized = true ;
3036+ rootlibdir = " lib" ;
3037+ gSystem ->PrependPathName (GetRootSys (), rootlibdir);
3038+ return rootlibdir;
3039+ #else
3040+ return TROOT::GetSharedLibDir ();
3041+ #endif
3042+ }
3043+
3044+ // //////////////////////////////////////////////////////////////////////////////
3045+ // / Get the shared libraries directory in the installation. Static utility function.
3046+ // /
30203047// / This function inspects the libraries currently loaded in the process to
30213048// / locate the ROOT Core library. Once found, it extracts and returns the
30223049// / directory containing that library. If the ROOT Core library was not found,
@@ -3025,9 +3052,9 @@ const TString& TROOT::GetBinDir() {
30253052// / The result is cached in a static variable so the lookup is only performed
30263053// / once per process, and the implementation is platform-specific.
30273054// /
3028- // / \return The directory path (as a `TString`) containing the ROOT core library .
3055+ // / \return The directory path (as a `TString`) containing the ROOT shared libraries .
30293056
3030- const TString &TROOT::GetLibDir ()
3057+ const TString &TROOT::GetSharedLibDir ()
30313058{
30323059 static bool haveLooked = false ;
30333060 static TString rootlibdir;
@@ -3057,9 +3084,35 @@ const TString &TROOT::GetLibDir()
30573084
30583085#elif defined(_WIN32)
30593086
3060- // Or Windows, the original hardcoded path is kept for now.
3061- rootlibdir = " lib" ;
3062- gSystem ->PrependPathName (GetRootSys (), rootlibdir);
3087+ HMODULE modules[1024 ];
3088+ DWORD needed = 0 ;
3089+
3090+ HANDLE process = GetCurrentProcess ();
3091+ if (EnumProcessModules (process, modules, sizeof (modules), &needed)) {
3092+ const unsigned int count = needed / sizeof (HMODULE);
3093+
3094+ for (unsigned int i = 0 ; i < count; ++i) {
3095+ wchar_t wpath[MAX_PATH];
3096+ DWORD len = GetModuleFileNameW (modules[i], wpath, MAX_PATH);
3097+ if (!len)
3098+ continue ;
3099+
3100+ fs::path p (wpath);
3101+ if (p.filename () == TO_LITERAL (LIB_CORE_NAME)) {
3102+
3103+ // Convert UTF-16 to UTF-8 explicitly
3104+ const std::wstring wdir = p.parent_path ().wstring ();
3105+
3106+ int utf8len = WideCharToMultiByte (CP_UTF8, 0 , wdir.c_str (), -1 , nullptr , 0 , nullptr , nullptr );
3107+
3108+ std::string utf8dir (utf8len - 1 , ' \0 ' );
3109+ WideCharToMultiByte (CP_UTF8, 0 , wdir.c_str (), -1 , utf8dir.data (), utf8len, nullptr , nullptr );
3110+
3111+ rootlibdir = utf8dir.c_str ();
3112+ break ;
3113+ }
3114+ }
3115+ }
30633116
30643117#else
30653118
@@ -3083,17 +3136,6 @@ const TString &TROOT::GetLibDir()
30833136 return rootlibdir;
30843137}
30853138
3086- // //////////////////////////////////////////////////////////////////////////////
3087- // / Get the shared libraries directory in the installation. Static utility function.
3088-
3089- const TString& TROOT::GetSharedLibDir () {
3090- #if defined(R__WIN32)
3091- return TROOT::GetBinDir ();
3092- #else
3093- return TROOT::GetLibDir ();
3094- #endif
3095- }
3096-
30973139// //////////////////////////////////////////////////////////////////////////////
30983140// / Get the include directory in the installation. Static utility function.
30993141
0 commit comments