diff --git a/3d-viewer/3d_rendering/raytracing/render_3d_raytrace_base.cpp b/3d-viewer/3d_rendering/raytracing/render_3d_raytrace_base.cpp
index 81e37c389e..b6caeae943 100644
--- a/3d-viewer/3d_rendering/raytracing/render_3d_raytrace_base.cpp
+++ b/3d-viewer/3d_rendering/raytracing/render_3d_raytrace_base.cpp
@@ -32,7 +32,7 @@
 #include "../color_rgba.h"
 #include "3d_fastmath.h"
 #include "3d_math.h"
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <core/profile.h>        // To use GetRunningMicroSecs or another profiling utility
 #include <wx/log.h>
 
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index b9d0a957eb..d972808f9b 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -187,6 +187,7 @@ set( KICOMMON_SRCS
     searchhelpfilefullpath.cpp
     string_utils.cpp
     systemdirsappend.cpp
+    thread_pool.cpp
     ui_events.cpp
     trace_helpers.cpp
     wildcards_and_files_ext.cpp
@@ -308,6 +309,7 @@ target_include_directories( kicommon
         $<TARGET_PROPERTY:kiapi,INTERFACE_INCLUDE_DIRECTORIES>
         $<TARGET_PROPERTY:picosha2,INTERFACE_INCLUDE_DIRECTORIES>
         $<TARGET_PROPERTY:nlohmann_json_schema_validator,INTERFACE_INCLUDE_DIRECTORIES>
+        $<TARGET_PROPERTY:thread-pool,INTERFACE_INCLUDE_DIRECTORIES>
     )
 
 add_dependencies( kicommon pegtl version_header )
diff --git a/common/advanced_config.cpp b/common/advanced_config.cpp
index 6a69d3317a..bfe14b4469 100644
--- a/common/advanced_config.cpp
+++ b/common/advanced_config.cpp
@@ -124,6 +124,7 @@ static const wxChar EnableSnapAnchorsDebug[] = wxT( "EnableSnapAnchorsDebug" );
 static const wxChar MinParallelAngle[] = wxT( "MinParallelAngle" );
 static const wxChar HoleWallPaintingMultiplier[] = wxT( "HoleWallPaintingMultiplier" );
 static const wxChar MsgPanelShowUuids[] = wxT( "MsgPanelShowUuids" );
+static const wxChar MaximumThreads[] = wxT( "MaximumThreads" );
 
 } // namespace KEYS
 
@@ -297,6 +298,8 @@ ADVANCED_CFG::ADVANCED_CFG()
     m_MinParallelAngle = 0.001;
     m_HoleWallPaintingMultiplier = 1.5;
 
+    m_MaximumThreads = 0;
+
     loadFromConfigFile();
 }
 
@@ -570,6 +573,10 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
                                                &m_MsgPanelShowUuids,
                                                m_MsgPanelShowUuids ) );
 
+    configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::MaximumThreads,
+                                                  &m_MaximumThreads, m_MaximumThreads,
+                                                  0, 500 ) );
+
     // Special case for trace mask setting...we just grab them and set them immediately
     // Because we even use wxLogTrace inside of advanced config
     wxString traceMasks;
diff --git a/common/design_block_info_impl.cpp b/common/design_block_info_impl.cpp
index a4783192a1..c133f504b6 100644
--- a/common/design_block_info_impl.cpp
+++ b/common/design_block_info_impl.cpp
@@ -28,7 +28,7 @@
 #include <lib_id.h>
 #include <progress_reporter.h>
 #include <string_utils.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <wildcards_and_files_ext.h>
 
 #include <kiplatform/io.h>
diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp
index eb1c92401c..ef063e1a9c 100644
--- a/common/gal/opengl/opengl_gal.cpp
+++ b/common/gal/opengl/opengl_gal.cpp
@@ -49,7 +49,7 @@
 
 #include <macros.h>
 #include <geometry/geometry_utils.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 
 #include <core/profile.h>
 #include <trace_helpers.h>
diff --git a/common/pgm_base.cpp b/common/pgm_base.cpp
index d852571e0a..75e42c50e7 100644
--- a/common/pgm_base.cpp
+++ b/common/pgm_base.cpp
@@ -63,7 +63,7 @@
 #include <settings/settings_manager.h>
 #include <string_utils.h>
 #include <systemdirsappend.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <trace_helpers.h>
 
 #include <widgets/wx_splash.h>
@@ -472,6 +472,10 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
 #ifdef KICAD_USE_SENTRY
     sentryInit();
 #endif
+
+    // Initialize the singleton instance
+    m_singleton.Init();
+
     wxString pgm_name;
 
     /// Should never happen but boost unit_test isn't playing nicely in some cases
diff --git a/libs/core/thread_pool.cpp b/common/thread_pool.cpp
similarity index 68%
rename from libs/core/thread_pool.cpp
rename to common/thread_pool.cpp
index b03a07d74f..f4e0e53f91 100644
--- a/libs/core/thread_pool.cpp
+++ b/common/thread_pool.cpp
@@ -21,21 +21,28 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
+#include <advanced_config.h>
+#include <pgm_base.h>
+#include <thread_pool.h>
 
-#include <core/thread_pool.h>
-
-// Under mingw, there is a problem with the destructor when creating a static instance
-// of a thread_pool: probably the DTOR is called too late, and the application hangs.
-// so we create it on the heap.
 static thread_pool* tp = nullptr;
 
 thread_pool& GetKiCadThreadPool()
 {
-#if 0   // Turn this on to disable multi-threading for debugging
-    if( !tp ) tp = new thread_pool( 1 );
-#else
-    if( !tp ) tp = new thread_pool;
-#endif
+    if( tp )
+        return *tp;
+
+    // If we have a PGM_BASE, use its thread pool
+    if( PGM_BASE* pgm = PgmOrNull() )
+    {
+        tp = &pgm->GetThreadPool();
+        return *tp;
+    }
+
+    // Otherwise, we are running in scripting or some other context where we don't have a PGM_BASE
+    // so we need to create our own thread pool
+    int num_threads = std::max( 0, ADVANCED_CFG::GetCfg().m_MaximumThreads );
+    tp = new thread_pool( num_threads );
 
     return *tp;
 }
diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp
index bd36fe16a3..f6f308a5dd 100644
--- a/eeschema/connection_graph.cpp
+++ b/eeschema/connection_graph.cpp
@@ -47,7 +47,7 @@
 #include <project/net_settings.h>
 #include <widgets/ui_common.h>
 #include <string_utils.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <wx/log.h>
 
 #include <advanced_config.h> // for realtime connectivity switch in release builds
diff --git a/eeschema/sim/spice_library_parser.cpp b/eeschema/sim/spice_library_parser.cpp
index 64008e55c4..dbb0f11920 100644
--- a/eeschema/sim/spice_library_parser.cpp
+++ b/eeschema/sim/spice_library_parser.cpp
@@ -26,7 +26,7 @@
 
 #include <utility>
 
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <ki_exception.h>
 #include <sim/sim_library_spice.h>
 #include <sim/spice_grammar.h>
diff --git a/include/advanced_config.h b/include/advanced_config.h
index f9c4134950..1421b5e05b 100644
--- a/include/advanced_config.h
+++ b/include/advanced_config.h
@@ -722,6 +722,15 @@ public:
      */
     double m_HoleWallPaintingMultiplier;
 
+    /**
+     * Default value for the maximum number of threads to use for parallel processing.
+     * Setting this value to 0 or less will mean that we use the number of cores available
+     *
+     * Setting name: "MaximumThreads"
+     * Default value: 0
+     */
+    int m_MaximumThreads;
+
 ///@}
 
 private:
diff --git a/include/pgm_base.h b/include/pgm_base.h
index 3608101e16..e43906fca9 100644
--- a/include/pgm_base.h
+++ b/include/pgm_base.h
@@ -32,6 +32,7 @@
 #define  PGM_BASE_H_
 
 #include <kicommon.h>
+#include <singleton.h>
 #include <exception>
 #include <map>
 #include <vector>
@@ -104,33 +105,13 @@ public:
     PGM_BASE();
     virtual ~PGM_BASE();
 
-#if 0
-    /*
-
-    Derived classes must implement these two functions: OnPgmInit() and
-    OnPgmExit(), and since they are only called from same source file as their
-    implementation, these need not be virtual here. In fact, in the case of
-    python project manager's class PGM_PYTHON, these functions are actually
-    written in python. In total there are three implementations, corresponding
-    to the three defines given by kiface.h's KFCTL_* #defines.
-
-    */
-
-    /**
-     * This is the first executed function (like main() ).
-     *
-     * @return true if the application can be started.
-     */
-    virtual bool OnPgmInit() = 0;           // call this from wxApp::OnInit()
-
-    virtual void OnPgmExit() = 0;           // call this from wxApp::OnExit()
-#endif
-
     /**
      * Builds the UTF8 based argv variable
      */
     void BuildArgvUtf8();
 
+    BS::thread_pool& GetThreadPool() { return *m_singleton.m_ThreadPool; }
+
     /**
      * Specific to MacOSX (not used under Linux or Windows).
      *
@@ -429,6 +410,8 @@ protected:
 
     wxString        m_text_editor;
 
+    KICAD_SINGLETON m_singleton;
+
 #ifdef KICAD_USE_SENTRY
     wxFileName      m_sentry_optin_fn;
     wxFileName      m_sentry_uid_fn;
diff --git a/include/singleton.h b/include/singleton.h
new file mode 100644
index 0000000000..04e934540b
--- /dev/null
+++ b/include/singleton.h
@@ -0,0 +1,51 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KICAD_SINGLETON_H
+#define KICAD_SINGLETON_H
+
+#include <advanced_config.h>
+#include <bs_thread_pool.hpp>
+#include <gal/opengl/gl_context_mgr.h>
+
+class KICAD_SINGLETON
+{
+public:
+    KICAD_SINGLETON(){};
+
+    ~KICAD_SINGLETON()
+    {
+        // This will wait for all threads to finish and then join them to the main thread
+        delete m_ThreadPool;
+
+        m_ThreadPool = nullptr;
+    };
+
+
+    void Init()
+    {
+        int num_threads = std::max( 0, ADVANCED_CFG::GetCfg().m_MaximumThreads );
+        m_ThreadPool = new BS::thread_pool( num_threads );
+    }
+
+    BS::thread_pool* m_ThreadPool;
+};
+
+
+#endif // KICAD_SINGLETON_H
\ No newline at end of file
diff --git a/libs/core/include/core/thread_pool.h b/include/thread_pool.h
similarity index 95%
rename from libs/core/include/core/thread_pool.h
rename to include/thread_pool.h
index 90a0bd87ad..1ccf936ab5 100644
--- a/libs/core/include/core/thread_pool.h
+++ b/include/thread_pool.h
@@ -26,6 +26,7 @@
 #define INCLUDE_THREAD_POOL_H_
 
 #include <bs_thread_pool.hpp>
+#include <import_export.h>
 
 using thread_pool = BS::thread_pool;
 
@@ -36,7 +37,7 @@ using thread_pool = BS::thread_pool;
  *
  * @return Reference to the current (potentially newly constructed) thread pool
  */
-thread_pool& GetKiCadThreadPool();
+APIEXPORT thread_pool& GetKiCadThreadPool();
 
 
 #endif /* INCLUDE_THREAD_POOL_H_ */
diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt
index e295f0f73f..917460a985 100644
--- a/kicad/CMakeLists.txt
+++ b/kicad/CMakeLists.txt
@@ -167,6 +167,7 @@ else()
         common
         gal
         common      #repeated due to a circular dependency between gal and common
+        kicommon
         core
         ${wxWidgets_LIBRARIES}
         )
@@ -176,6 +177,7 @@ else()
         common
         gal
         common      #repeated due to a circular dependency between gal and common
+        kicommon
         core
         ${wxWidgets_LIBRARIES}
         )
diff --git a/kicad/update_manager.cpp b/kicad/update_manager.cpp
index 522685b1db..239b60e3ab 100644
--- a/kicad/update_manager.cpp
+++ b/kicad/update_manager.cpp
@@ -49,7 +49,7 @@
 
 #include <background_jobs_monitor.h>
 
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 
 #include <build_version.h>
 
diff --git a/libs/core/CMakeLists.txt b/libs/core/CMakeLists.txt
index 6c351a3143..1e8bc33dfe 100644
--- a/libs/core/CMakeLists.txt
+++ b/libs/core/CMakeLists.txt
@@ -10,7 +10,6 @@ add_library( core STATIC
     observable.cpp
     profile.cpp
     utf8.cpp
-    thread_pool.cpp
     version_compare.cpp
     wx_stl_compat.cpp
 )
@@ -21,7 +20,6 @@ target_link_libraries( core PUBLIC
 
 target_include_directories( core PUBLIC
     ${CMAKE_CURRENT_SOURCE_DIR}/include
-    $<TARGET_PROPERTY:thread-pool,INTERFACE_INCLUDE_DIRECTORIES>
     PRIVATE
     ${CMAKE_BINARY_DIR} # to get config.h
 )
\ No newline at end of file
diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp
index 284530ee69..78db938d3b 100644
--- a/pcbnew/board.cpp
+++ b/pcbnew/board.cpp
@@ -63,7 +63,7 @@
 #include <tool/tool_manager.h>
 #include <tool/selection_conditions.h>
 #include <string_utils.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <zone.h>
 #include <mutex>
 
diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp
index 5bcb169bfe..f5dae8b5d5 100644
--- a/pcbnew/connectivity/connectivity_algo.cpp
+++ b/pcbnew/connectivity/connectivity_algo.cpp
@@ -33,7 +33,7 @@
 #include <progress_reporter.h>
 #include <geometry/geometry_utils.h>
 #include <board_commit.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <pcb_shape.h>
 
 #include <wx/log.h>
diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp
index 43df014541..6e842e07e6 100644
--- a/pcbnew/connectivity/connectivity_data.cpp
+++ b/pcbnew/connectivity/connectivity_data.cpp
@@ -40,7 +40,7 @@
 #include <geometry/shape_circle.h>
 #include <ratsnest/ratsnest_data.h>
 #include <progress_reporter.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <trigo.h>
 #include <drc/drc_rtree.h>
 
diff --git a/pcbnew/dialogs/dialog_export_odbpp.cpp b/pcbnew/dialogs/dialog_export_odbpp.cpp
index 5b2cd640ac..9f5423826b 100644
--- a/pcbnew/dialogs/dialog_export_odbpp.cpp
+++ b/pcbnew/dialogs/dialog_export_odbpp.cpp
@@ -37,7 +37,7 @@
 
 #include <set>
 #include <vector>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <io/io_mgr.h>
 #include <jobs/job_export_pcb_odb.h>
 #include <pcb_io/pcb_io_mgr.h>
diff --git a/pcbnew/drc/drc_cache_generator.cpp b/pcbnew/drc/drc_cache_generator.cpp
index 5a5b5441b4..c219c4744d 100644
--- a/pcbnew/drc/drc_cache_generator.cpp
+++ b/pcbnew/drc/drc_cache_generator.cpp
@@ -24,7 +24,7 @@
 #include <common.h>
 #include <board_design_settings.h>
 #include <footprint.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <zone.h>
 #include <connectivity/connectivity_data.h>
 #include <drc/drc_engine.h>
diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp
index e4ceab9bb7..f1211524d1 100644
--- a/pcbnew/drc/drc_engine.cpp
+++ b/pcbnew/drc/drc_engine.cpp
@@ -41,7 +41,7 @@
 #include <pad.h>
 #include <pcb_track.h>
 #include <core/profile.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <zone.h>
 
 
diff --git a/pcbnew/drc/drc_test_provider_connection_width.cpp b/pcbnew/drc/drc_test_provider_connection_width.cpp
index c543a1da47..49f292d946 100644
--- a/pcbnew/drc/drc_test_provider_connection_width.cpp
+++ b/pcbnew/drc/drc_test_provider_connection_width.cpp
@@ -45,7 +45,7 @@
 #include <math/vector2d.h>
 #include <pcb_shape.h>
 #include <progress_reporter.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <pcb_track.h>
 #include <pad.h>
 #include <zone.h>
diff --git a/pcbnew/drc/drc_test_provider_copper_clearance.cpp b/pcbnew/drc/drc_test_provider_copper_clearance.cpp
index a5364e98d8..039c594275 100644
--- a/pcbnew/drc/drc_test_provider_copper_clearance.cpp
+++ b/pcbnew/drc/drc_test_provider_copper_clearance.cpp
@@ -29,7 +29,7 @@
 #include <pcb_shape.h>
 #include <pad.h>
 #include <pcb_track.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <zone.h>
 
 #include <geometry/seg.h>
diff --git a/pcbnew/drc/drc_test_provider_disallow.cpp b/pcbnew/drc/drc_test_provider_disallow.cpp
index 3177125708..66cd3797f9 100644
--- a/pcbnew/drc/drc_test_provider_disallow.cpp
+++ b/pcbnew/drc/drc_test_provider_disallow.cpp
@@ -31,7 +31,7 @@
 #include <drc/drc_test_provider.h>
 #include <pad.h>
 #include <progress_reporter.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <zone.h>
 #include <mutex>
 
diff --git a/pcbnew/drc/drc_test_provider_sliver_checker.cpp b/pcbnew/drc/drc_test_provider_sliver_checker.cpp
index ed61c01b19..d546f8b0b1 100644
--- a/pcbnew/drc/drc_test_provider_sliver_checker.cpp
+++ b/pcbnew/drc/drc_test_provider_sliver_checker.cpp
@@ -33,7 +33,7 @@
 #include <drc/drc_test_provider.h>
 #include <advanced_config.h>
 #include <progress_reporter.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 
 /*
     Checks for slivers in copper layers
diff --git a/pcbnew/drc/drc_test_provider_track_angle.cpp b/pcbnew/drc/drc_test_provider_track_angle.cpp
index 26ed943766..339c732931 100644
--- a/pcbnew/drc/drc_test_provider_track_angle.cpp
+++ b/pcbnew/drc/drc_test_provider_track_angle.cpp
@@ -21,7 +21,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include "geometry/eda_angle.h"
 #include <numbers>
 #include <pcb_track.h>
diff --git a/pcbnew/drc/drc_test_provider_track_segment_length.cpp b/pcbnew/drc/drc_test_provider_track_segment_length.cpp
index 2147d9c5a0..af127ca240 100644
--- a/pcbnew/drc/drc_test_provider_track_segment_length.cpp
+++ b/pcbnew/drc/drc_test_provider_track_segment_length.cpp
@@ -21,7 +21,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <pcb_track.h>
 #include <drc/drc_engine.h>
 #include <drc/drc_item.h>
diff --git a/pcbnew/drc/drc_test_provider_zone_connections.cpp b/pcbnew/drc/drc_test_provider_zone_connections.cpp
index dd77db80da..7c42c2b9b8 100644
--- a/pcbnew/drc/drc_test_provider_zone_connections.cpp
+++ b/pcbnew/drc/drc_test_provider_zone_connections.cpp
@@ -28,7 +28,7 @@
 #include <footprint.h>
 #include <pad.h>
 #include <pcb_track.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 
 #include <geometry/shape_line_chain.h>
 #include <geometry/shape_poly_set.h>
diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp
index a75d7b0a09..915c5267ff 100644
--- a/pcbnew/files.cpp
+++ b/pcbnew/files.cpp
@@ -29,7 +29,7 @@
 #include <confirm.h>
 #include <kidialog.h>
 #include <core/arraydim.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <dialog_HTML_reporter_base.h>
 #include <gestfich.h>
 #include <pcb_edit_frame.h>
diff --git a/pcbnew/footprint_info_impl.cpp b/pcbnew/footprint_info_impl.cpp
index f101b93dc6..9291e6b72f 100644
--- a/pcbnew/footprint_info_impl.cpp
+++ b/pcbnew/footprint_info_impl.cpp
@@ -31,7 +31,7 @@
 #include <lib_id.h>
 #include <progress_reporter.h>
 #include <string_utils.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <wildcards_and_files_ext.h>
 
 #include <kiplatform/io.h>
diff --git a/pcbnew/tracks_cleaner.cpp b/pcbnew/tracks_cleaner.cpp
index bd72b79f74..1216b046a1 100644
--- a/pcbnew/tracks_cleaner.cpp
+++ b/pcbnew/tracks_cleaner.cpp
@@ -31,7 +31,7 @@
 #include <cleanup_item.h>
 #include <connectivity/connectivity_algo.h>
 #include <connectivity/connectivity_data.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <lset.h>
 #include <tool/tool_manager.h>
 #include <tools/pcb_actions.h>
diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp
index f05ea2e1c1..b9a3144545 100644
--- a/pcbnew/zone_filler.cpp
+++ b/pcbnew/zone_filler.cpp
@@ -47,7 +47,7 @@
 #include <geometry/geometry_utils.h>
 #include <geometry/vertex_set.h>
 #include <kidialog.h>
-#include <core/thread_pool.h>
+#include <thread_pool.h>
 #include <math/util.h>      // for KiROUND
 #include "zone_filler.h"
 
diff --git a/qa/tests/api/test_api_module.cpp b/qa/tests/api/test_api_module.cpp
index ccbbf056af..3375a5e26e 100644
--- a/qa/tests/api/test_api_module.cpp
+++ b/qa/tests/api/test_api_module.cpp
@@ -19,11 +19,16 @@
 
 #include <boost/test/unit_test.hpp>
 #include <wx/app.h>
+
+#include <mock_pgm_base.h>
+#include <pgm_base.h>
 #include <qa_utils/wx_utils/wx_assert.h>
 
 
 bool init_unit_test()
 {
+    SetPgm( new MOCK_PGM_BASE() );
+
     boost::unit_test::framework::master_test_suite().p_name.value = "IPC API tests";
 
     wxApp::SetInstance( new wxAppConsole );
@@ -31,7 +36,12 @@ bool init_unit_test()
     bool ok = wxInitialize( boost::unit_test::framework::master_test_suite().argc,
                             boost::unit_test::framework::master_test_suite().argv );
 
-    wxSetAssertHandler( &KI_TEST::wxAssertThrower );
+    if( ok )
+    {
+        wxSetAssertHandler( &KI_TEST::wxAssertThrower );
+
+        Pgm().InitPgm( true, true, true );
+    }
 
     return ok;
 }
diff --git a/qa/tests/common/test_module.cpp b/qa/tests/common/test_module.cpp
index 4e6182ae8c..523576b8ca 100644
--- a/qa/tests/common/test_module.cpp
+++ b/qa/tests/common/test_module.cpp
@@ -38,10 +38,7 @@ bool init_unit_test()
     bool ok = wxInitialize();
 
     if( ok )
-    {
-        // need these for library image functions
-        wxInitAllImageHandlers();
-    }
+        Pgm().InitPgm( true, true, true );
 
     return ok;
 }
diff --git a/qa/tests/eeschema/CMakeLists.txt b/qa/tests/eeschema/CMakeLists.txt
index 8bc9ce02df..fa4c3e145a 100644
--- a/qa/tests/eeschema/CMakeLists.txt
+++ b/qa/tests/eeschema/CMakeLists.txt
@@ -105,6 +105,7 @@ target_link_libraries( qa_eeschema
 PRIVATE
     eeschema_kiface_objects
     common
+    kicommon
     pcbcommon
     3d-viewer
     scripting
diff --git a/qa/tests/pcbnew/test_module.cpp b/qa/tests/pcbnew/test_module.cpp
index 6c99279713..99c951f61c 100644
--- a/qa/tests/pcbnew/test_module.cpp
+++ b/qa/tests/pcbnew/test_module.cpp
@@ -27,6 +27,8 @@
 #include <boost/test/unit_test.hpp>
 #include <kiplatform/app.h>
 #include <mock_pgm_base.h>
+#include <settings/settings_manager.h>
+#include <pcbnew_settings.h>
 
 #include <wx/image.h>
 #include <wx/init.h>
@@ -38,12 +40,18 @@ bool init_unit_test()
     KIPLATFORM::APP::Init();
     boost::unit_test::framework::master_test_suite().p_name.value = "Pcbnew module tests";
 
-    bool ok = wxInitialize();
+    wxApp::SetInstance( new wxAppConsole );
+
+    bool ok = wxInitialize( boost::unit_test::framework::master_test_suite().argc,
+                            boost::unit_test::framework::master_test_suite().argv );
 
     if( ok )
     {
-        // need these for library image functions
-        wxInitAllImageHandlers();
+        wxSetAssertHandler( &KI_TEST::wxAssertThrower );
+
+        Pgm().InitPgm( true, true, true );
+        Pgm().GetSettingsManager().RegisterSettings( new PCBNEW_SETTINGS, false );
+        Pgm().GetSettingsManager().Load();
     }
 
     return ok;