From d0d4c4065be935428b3cd906332d846f92d36a58 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@gmail.com>
Date: Wed, 8 Jan 2025 18:21:26 +0800
Subject: [PATCH] Make run from build dir work for debug executables

When using KICAD_RUN_FROM_BUILD_DIR, at least on Linux, not all
executables can assume executable/.. is the build directory - instead
iterate upwards until a CMakeCache.txt file in encountered.

Without this, for example, the PNS log viewer complains about missing
JSON schema files.
---
 common/paths.cpp | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/common/paths.cpp b/common/paths.cpp
index 93f95ed41e..c13cdeb10e 100644
--- a/common/paths.cpp
+++ b/common/paths.cpp
@@ -148,6 +148,28 @@ wxString PATHS::GetDefaultUserProjectsPath()
 }
 
 
+/**
+ * Get the CMake build root directory for the current executable
+ * (which assumes the executable is in a build directory).
+ *
+ * This is done because not all executable are located at the same
+ * depth in the build directory.
+ */
+static wxString getCmakeBuildRoot()
+{
+    wxFileName fn = PATHS::GetExecutablePath();
+    // The build directory will have a CMakeCache.txt file in it
+    while( fn.GetDirCount() > 0 && !wxFileExists( fn.GetPathWithSep() + wxT( "CMakeCache.txt" ) ) )
+    {
+        fn.RemoveLastDir();
+    }
+
+    wxASSERT_MSG( fn.GetDirCount() > 0, wxT( "Could not find CMake build root directory" ) );
+
+    return fn.GetPath();
+}
+
+
 wxString PATHS::GetStockDataPath( bool aRespectRunFromBuildDir )
 {
     wxString path;
@@ -166,7 +188,7 @@ wxString PATHS::GetStockDataPath( bool aRespectRunFromBuildDir )
 #elif defined( __WXMSW__ )
         path = getWindowsKiCadRoot();
 #else
-        path = GetExecutablePath() + wxT( ".." );
+        path = getCmakeBuildRoot();
 #endif
     }
     else if( wxGetEnv( wxT( "KICAD_STOCK_DATA_HOME" ), &path ) && !path.IsEmpty() )