Author Topic: The library search path is not included in the PATH in the compilergcc plugin  (Read 3979 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6095
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Hi, I just build C::B trunk yesterday, and I found that if I link to a dll file directly, and the dll file is in the library search path. The old C::B can run the executable. But the latest failed, because it said the exe can't find the dll file.

Which means the PATH is not including the library search path?

I looked at the change history of the compiler gcc folder, and still not sure which commit cause this issue. The old C::B I'm using is built from 2025-02.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Miguel Gimenez

  • Developer
  • Lives here!
  • *****
  • Posts: 1772
I would bet r13731 (Running compiled program fails because of wrong PATH) is related.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6095
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
I would bet r13731 (Running compiled program fails because of wrong PATH) is related.

Thanks.

Yes, I think this is related.

Especially here:

Code
@@ -1445,8 +1453,10 @@ int CompilerGCC::DoRunQueue()
     else
         m_timerIdleWakeUp.Start(100);
 
-    // restore dynamic linker path
+    // restore old dynamic linker path
     wxSetEnv(CB_LIBRARY_ENVVAR, oldLibPath);
+    // restore old PATH environment
+    wxSetEnv("PATH", oldPath);
 
     delete cmd;
     return DoRunQueue();

The old "PATH" get restored.

I think when we click the "run" button on the toolbar, we should also set the PATH, and when run finished, we should restore the PATH.

Hi, Morten, can you have a look?
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6095
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Code

-------------- Run: Debug in wx-sample (compiler: GNU GCC Compiler)---------------

Checking for existence: F\code\threepp\cb\bin\Debug\wx-sample.exe
Set variable: PATH=.;F\code\threepp\build\bin;D:/code/msys2/mingw64/lib;D:\code\msys2\mingw64\bin;D:\code\msys2\mingw64;C:\Windows\System32;C:\Windows;...
Set variable: PATH=D:\code\msys2\mingw64\bin;D:\code\msys2\mingw64\bin;D:\code\msys2\mingw64;C:\Windows\System32;C:\Windows;...
Executing: "F\code\threepp\cb\bin\Debug\wx-sample.exe"  (in F\code\threepp\cb\.)


Look at the log above, it looks like the "Set variable: PATH" has run 2 times when I click the "Run" button.

The first time, the project's current folder "." (the dot), and the library search path (E:\F\code\threepp\build\bin) was already included in the PATH.

But I see the second time the PATH get restored.

The bad thing is: the executing happens after the PATH get restored.

Code

    // restore old dynamic linker path
    wxSetEnv(CB_LIBRARY_ENVVAR, oldLibPath);
    // restore old PATH environment
    wxSetEnv("PATH", oldPath);

    delete cmd;
    return DoRunQueue();
}

The above code snippet is the last section of the DoRunQueue function, and I guess it has some recursive calls, and it looks like the actual running of the executable is inside the recursive call?

So, to solve this issue, maybe, we need to "restore" the PATH variable after the inner "DoRunQueue()"?
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6095
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
OK, it looks like under Windows system, CB_LIBRARY_ENVVAR is defined as "PATH". See below definition in prep.h


Code
#if defined(__APPLE__) && defined(__MACH__)
    #define CB_LIBRARY_ENVVAR _T("DYLD_LIBRARY_PATH")
#elif !defined(__WXMSW__)
    #define CB_LIBRARY_ENVVAR _T("LD_LIBRARY_PATH")
#else
    #define CB_LIBRARY_ENVVAR _T("PATH")
#endif

Now, the code here is: we set the "PATH" 2 times under Windows. The error is: the second time we set the "PATH", we just override the lib search path!



If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6095
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Code
diff --git a/src/plugins/compilergcc/compilergcc.cpp b/src/plugins/compilergcc/compilergcc.cpp
index e113723..4b25f43 100644
--- a/src/plugins/compilergcc/compilergcc.cpp
+++ b/src/plugins/compilergcc/compilergcc.cpp
@@ -1375,8 +1375,6 @@ int CompilerGCC::DoRunQueue()
 
     wxString oldLibPath; // keep old PATH/LD_LIBRARY_PATH contents
     wxGetEnv(CB_LIBRARY_ENVVAR, &oldLibPath);
-    wxString oldPath;    // keep old PATH environment
-    wxGetEnv("PATH", &oldPath);
 
     bool pipe = true;
     int flags = wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER;
@@ -1389,14 +1387,18 @@ int CompilerGCC::DoRunQueue()
         // setup dynamic linker path
         wxString newLibPath = cbGetDynamicLinkerPathForTarget(m_pProject, cmd->target);
         newLibPath = cbMergeLibPaths(oldLibPath, newLibPath);
+
+        // Under Windows OS, the CB_LIBRARY_ENVVAR is defined as "PATH", see the prep.h.
+        // So, the newLibPath already contains the "library search path" + "old PATH".
+        // We have to "prepend" the below compiler bin path "newCompilerBinPath" to the system "PATH",
+        // otherwise, the previous PATH setting is lost!
+# if defined(__WXMSW__)
+        wxString newCompilerBinPath = cbGetCompilerBinPathForTarget(m_pProject, cmd->target);
+        newLibPath = cbMergeLibPaths(newLibPath, newCompilerBinPath);
+#endif
+
         wxSetEnv(CB_LIBRARY_ENVVAR, newLibPath);
         LogMessage(wxString(_("Set variable: ")) + CB_LIBRARY_ENVVAR wxT("=") + newLibPath, cltInfo);
-
-        // setup PATH environment
-        wxString newPath = cbGetCompilerBinPathForTarget(m_pProject, cmd->target);
-        newPath = cbMergeLibPaths(oldPath, newPath);
-        wxSetEnv("PATH", newPath);
-        LogMessage(wxString(_("Set variable: PATH=")) + newPath, cltInfo);
     }
 
     // log message here, so the logging for run executable commands is done after the log message
@@ -1455,8 +1457,6 @@ int CompilerGCC::DoRunQueue()
 
     // restore old dynamic linker path
     wxSetEnv(CB_LIBRARY_ENVVAR, oldLibPath);
-    // restore old PATH environment
-    wxSetEnv("PATH", oldPath);
 
     delete cmd;
     return DoRunQueue();


Hi, this patch should fix the issue. We don't need to set the "PATH" two times, and the compiler bin path is prepend to the PATH just as what Morten did in the commit.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.