From 018e383c43b8d5a28d873b52d5770ca04b2b5a3e Mon Sep 17 00:00:00 2001 From: Guillaume Paran Date: Thu, 4 Feb 2021 19:30:21 +0100 Subject: [PATCH 1/9] Add PluginManager callback for sys.path auto-adds --- Plugin/src/SofaPython3/PythonEnvironment.cpp | 42 +++++++++++++++++++- Plugin/src/SofaPython3/PythonEnvironment.h | 6 +++ Plugin/src/SofaPython3/initModule.cpp | 1 + 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/Plugin/src/SofaPython3/PythonEnvironment.cpp b/Plugin/src/SofaPython3/PythonEnvironment.cpp index 4959b7f5..ed7aa730 100644 --- a/Plugin/src/SofaPython3/PythonEnvironment.cpp +++ b/Plugin/src/SofaPython3/PythonEnvironment.cpp @@ -118,6 +118,8 @@ PythonEnvironmentData* PythonEnvironment::getStaticData() return m_staticdata; } +std::string PythonEnvironment::pluginLibraryPath = ""; + SOFAPYTHON3_API py::module PythonEnvironment::importFromFile(const std::string& module, const std::string& path, py::object* globals) { PythonEnvironment::gil lock; @@ -238,6 +240,17 @@ void PythonEnvironment::Init() // python modules are automatically reloaded at each scene loading //setAutomaticModuleReload( true ); + + // Initialize pluginLibraryPath by reading PluginManager's map + std::map& map = PluginManager::getInstance().getPluginMap(); + for( const auto& elem : map) + { + Plugin p = elem.second; + if ( p.getModuleName() == sofa_tostring(SOFA_TARGET) ) + { + pluginLibraryPath = elem.first; + } + } } void PythonEnvironment::executePython(std::function cb) @@ -332,7 +345,7 @@ void PythonEnvironment::addPythonModulePathsForPlugins(const std::string& plugin if(!added) { - msg_warning("PythonEnvironment") << "No python dir found in " << pluginsDirectory; + msg_info("PythonEnvironment") << "No python3 dir found in " << pluginsDirectory; } } @@ -355,6 +368,33 @@ void PythonEnvironment::addPythonModulePathsForPluginsByName(const std::string& msg_warning("PythonEnvironment") << pluginName << " not found in PluginManager's map."; } +void PythonEnvironment::addPluginManagerCallback() +{ + PluginManager::getInstance().addOnPluginLoadedCallback(pluginLibraryPath, + [](const std::string& pluginLibraryPath, const Plugin& plugin) { + // WARNING: + // Loaded plugin must be organized like plugin_name/lib/plugin_name.so + + // pluginRoot must be 2 levels above the library + std::string pluginRoot = FileSystem::getParentDirectory( + FileSystem::getParentDirectory( + pluginLibraryPath + )); + // pluginRoot basename must be pluginName + std::string pluginName = plugin.getModuleName(); + if(FileSystem::stripDirectory(pluginRoot) == pluginName) + { + PythonEnvironment::addPythonModulePathsForPlugins(pluginRoot); + } + } + ); +} + +void PythonEnvironment::removePluginManagerCallback() +{ + PluginManager::getInstance().removeOnPluginLoadedCallback(pluginLibraryPath); +} + // some basic RAII stuff to handle init/termination cleanly namespace diff --git a/Plugin/src/SofaPython3/PythonEnvironment.h b/Plugin/src/SofaPython3/PythonEnvironment.h index f74e968f..aa12fba8 100644 --- a/Plugin/src/SofaPython3/PythonEnvironment.h +++ b/Plugin/src/SofaPython3/PythonEnvironment.h @@ -57,6 +57,11 @@ class SOFAPYTHON3_API PythonEnvironment const std::string& path, pybind11::object* globals = nullptr); + /// Add a new callback in PluginManager to auto-add future + /// loaded plugins to sys.path + static void addPluginManagerCallback(); + static void removePluginManagerCallback(); + /// Add a path to sys.path, the list of search path for Python modules. static void addPythonModulePath(const std::string& path); @@ -134,6 +139,7 @@ class SOFAPYTHON3_API PythonEnvironment private: static PythonEnvironmentData* getStaticData() ; + static std::string pluginLibraryPath; }; } // namespace sofapython3 diff --git a/Plugin/src/SofaPython3/initModule.cpp b/Plugin/src/SofaPython3/initModule.cpp index 63b9857b..4c2cd7af 100644 --- a/Plugin/src/SofaPython3/initModule.cpp +++ b/Plugin/src/SofaPython3/initModule.cpp @@ -52,6 +52,7 @@ void initExternalModule() PythonEnvironment::Init(); first = false; } + PythonEnvironment::addPluginManagerCallback(); } const char* getModuleName() From 50ee47a3ea933cd8b480a7fd366d8da0bad04ba9 Mon Sep 17 00:00:00 2001 From: Guillaume Paran Date: Fri, 5 Feb 2021 18:27:40 +0100 Subject: [PATCH 2/9] [Plugin] Improve PluginManager callback for Windows install --- Plugin/src/SofaPython3/PythonEnvironment.cpp | 22 ++++++++------------ 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Plugin/src/SofaPython3/PythonEnvironment.cpp b/Plugin/src/SofaPython3/PythonEnvironment.cpp index ed7aa730..3493b5b8 100644 --- a/Plugin/src/SofaPython3/PythonEnvironment.cpp +++ b/Plugin/src/SofaPython3/PythonEnvironment.cpp @@ -365,26 +365,22 @@ void PythonEnvironment::addPythonModulePathsForPluginsByName(const std::string& return; } } - msg_warning("PythonEnvironment") << pluginName << " not found in PluginManager's map."; + msg_info("PythonEnvironment") << pluginName << " not found in PluginManager's map."; } void PythonEnvironment::addPluginManagerCallback() { PluginManager::getInstance().addOnPluginLoadedCallback(pluginLibraryPath, [](const std::string& pluginLibraryPath, const Plugin& plugin) { - // WARNING: - // Loaded plugin must be organized like plugin_name/lib/plugin_name.so - - // pluginRoot must be 2 levels above the library - std::string pluginRoot = FileSystem::getParentDirectory( - FileSystem::getParentDirectory( - pluginLibraryPath - )); - // pluginRoot basename must be pluginName - std::string pluginName = plugin.getModuleName(); - if(FileSystem::stripDirectory(pluginRoot) == pluginName) + // WARNING: loaded plugin must be organized like plugin_name/lib/plugin_name.so + for ( auto path : sofa::helper::system::PluginRepository.getPaths() ) { - PythonEnvironment::addPythonModulePathsForPlugins(pluginRoot); + std::string pluginRoot = FileSystem::cleanPath( path + "/" + plugin.getModuleName() ); + if ( FileSystem::isDirectory(pluginRoot) ) + { + addPythonModulePathsForPlugins(pluginRoot); + return; + } } } ); From ad081cdb2a2691e8416c3c3049b12fbc72256bb4 Mon Sep 17 00:00:00 2001 From: Guillaume Paran Date: Fri, 5 Feb 2021 20:25:19 +0100 Subject: [PATCH 3/9] FIX PythonEnvironment use FileSystem::exists --- Plugin/src/SofaPython3/PythonEnvironment.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugin/src/SofaPython3/PythonEnvironment.cpp b/Plugin/src/SofaPython3/PythonEnvironment.cpp index 3493b5b8..de719e20 100644 --- a/Plugin/src/SofaPython3/PythonEnvironment.cpp +++ b/Plugin/src/SofaPython3/PythonEnvironment.cpp @@ -376,7 +376,7 @@ void PythonEnvironment::addPluginManagerCallback() for ( auto path : sofa::helper::system::PluginRepository.getPaths() ) { std::string pluginRoot = FileSystem::cleanPath( path + "/" + plugin.getModuleName() ); - if ( FileSystem::isDirectory(pluginRoot) ) + if ( FileSystem::exists(pluginRoot) && FileSystem::isDirectory(pluginRoot) ) { addPythonModulePathsForPlugins(pluginRoot); return; From e4eba7d6fa910c78df643c9e476ae6249dac34bf Mon Sep 17 00:00:00 2001 From: Guillaume Paran Date: Mon, 15 Feb 2021 18:37:22 +0100 Subject: [PATCH 4/9] [SofaGui] Use new qt.conf.h for custom qt.conf loading at runtime --- .../SofaPython3/SofaGui/Module_SofaGui.cpp | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp b/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp index 16872c1d..2493e311 100644 --- a/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp +++ b/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp @@ -22,6 +22,11 @@ #include #include +#include +#include +#include +using sofa::helper::system::FileSystem; +#include #include "Binding_BaseGui.h" #include "Binding_GUIManager.h" @@ -55,6 +60,18 @@ PYBIND11_MODULE(Gui, m) { :members: )doc"; + std::string sofaPrefixAbsolute = sofa::helper::Utils::getSofaPathPrefix(); + std::string inputFilepath = FileSystem::cleanPath(sofaPrefixAbsolute + "/bin/qt.conf"); + bool success = sofa::gui::qt::loadQtConfWithCustomPrefix(inputFilepath, sofaPrefixAbsolute); + if(success) + { + msg_info("Sofa.Gui") << "Loaded qt.conf from " << inputFilepath << " customized with Prefix = " << sofaPrefixAbsolute; + } + else + { + msg_warning("Sofa.Gui") << "Failed loading and/or customizing qt.conf from " << inputFilepath; + } + // This is needed to make sure the GuiMain library (libSofaGuiMain.so) is correctly // linked since the GUIs are statically created during the load of the library. sofa::gui::initMain(); @@ -63,4 +80,5 @@ PYBIND11_MODULE(Gui, m) { moduleAddBaseGui(m); moduleAddGuiManager(m); } -} \ No newline at end of file + +} // namespace sofapython3 From fc7664ea45968025c6642987ea8ca6a2ff3ba413 Mon Sep 17 00:00:00 2001 From: Guillaume Paran Date: Fri, 19 Feb 2021 09:16:48 +0100 Subject: [PATCH 5/9] [Plugin] CLEAN PythonEnvironment messages --- Plugin/src/SofaPython3/PythonEnvironment.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugin/src/SofaPython3/PythonEnvironment.cpp b/Plugin/src/SofaPython3/PythonEnvironment.cpp index de719e20..2a0743e3 100644 --- a/Plugin/src/SofaPython3/PythonEnvironment.cpp +++ b/Plugin/src/SofaPython3/PythonEnvironment.cpp @@ -345,7 +345,7 @@ void PythonEnvironment::addPythonModulePathsForPlugins(const std::string& plugin if(!added) { - msg_info("PythonEnvironment") << "No python3 dir found in " << pluginsDirectory; + msg_info("SofaPython3") << "No python3 dir found in " << pluginsDirectory; } } @@ -365,7 +365,7 @@ void PythonEnvironment::addPythonModulePathsForPluginsByName(const std::string& return; } } - msg_info("PythonEnvironment") << pluginName << " not found in PluginManager's map."; + msg_info("SofaPython3") << pluginName << " not found in PluginManager's map."; } void PythonEnvironment::addPluginManagerCallback() From b4f78aa5c985fab59c017d60b689104b709514d1 Mon Sep 17 00:00:00 2001 From: Guillaume Paran Date: Fri, 19 Feb 2021 09:25:27 +0100 Subject: [PATCH 6/9] [Bindings] ADD current dir to RPATH --- bindings/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index 4257e2a0..ab23b7a3 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -8,12 +8,16 @@ endif() # This will set rpaths relative to SP3 plugin library if(UNIX) set(CMAKE_INSTALL_RPATH + "$ORIGIN" + "$$ORIGIN" "$ORIGIN/../lib" "$$ORIGIN/../lib" ) if(APPLE) set(CMAKE_MACOSX_RPATH ON) list(APPEND CMAKE_INSTALL_RPATH + "@loader_path" + "@executable_path" "@loader_path/../lib" "@executable_path/../lib" ) From 110c0628cf448d4b2a581ae613d1c78b12af9c32 Mon Sep 17 00:00:00 2001 From: Guillaume Paran Date: Fri, 19 Feb 2021 16:15:05 +0100 Subject: [PATCH 7/9] [Bindings] ADD debug log for qt.conf loading --- bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp b/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp index 2493e311..f36daff3 100644 --- a/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp +++ b/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp @@ -70,6 +70,12 @@ PYBIND11_MODULE(Gui, m) { else { msg_warning("Sofa.Gui") << "Failed loading and/or customizing qt.conf from " << inputFilepath; + + std::cout << "qt_resource_data:" << std::endl; + for (int i = 0 ; i < qt_resource_data.size() ; ++i) { + std::cout << qt_resource_data[i]; + } + std::cout << std::endl; } // This is needed to make sure the GuiMain library (libSofaGuiMain.so) is correctly From 05bd39974363027c4ee3549f9894c3442318c018 Mon Sep 17 00:00:00 2001 From: Guillaume Paran Date: Wed, 31 Mar 2021 16:35:51 +0200 Subject: [PATCH 8/9] [GitHub] Update SOFA minimal binaries to v20.12.02 --- .github/workflows/macos.yml | 12 ++++++------ .github/workflows/ubuntu.yml | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index b608b482..730cfa3e 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -27,12 +27,12 @@ jobs: brew install ccache ninja boost eigen pybind11 python3 -m pip install numpy - - name: Download SOFA nightly build + - name: Download SOFA v20.12.02 run: | curl --output sofa.zip -L \ - https://ci.inria.fr/sofa-ci-dev/job/nightly-generate-binaries-v20.12/lastSuccessfulBuild/CI_SCOPE=binaries_minimal/artifact/MacOS/*zip*/MacOS.zip + https://ci.inria.fr/sofa-ci-dev/job/nightly-generate-binaries/CI_SCOPE=binaries_minimal/309/artifact/MacOS/*zip*/MacOS.zip - - name: Install SOFA nightly build + - name: Install SOFA v20.12.02 run: | sudo unzip sofa.zip -d temp sudo unzip temp/MacOS/`ls temp/MacOS/` -d temp @@ -105,12 +105,12 @@ jobs: brew install boost python3 -m pip install numpy - - name: Download SOFA nightly build + - name: Download SOFA v20.12.02 run: | curl --output sofa.zip -L \ - https://ci.inria.fr/sofa-ci-dev/job/nightly-generate-binaries-v20.12/lastSuccessfulBuild/CI_SCOPE=binaries_minimal/artifact/MacOS/*zip*/MacOS.zip + https://ci.inria.fr/sofa-ci-dev/job/nightly-generate-binaries/CI_SCOPE=binaries_minimal/309/artifact/MacOS/*zip*/MacOS.zip - - name: Install SOFA nightly build + - name: Install SOFA v20.12.02 run: | sudo unzip sofa.zip -d temp sudo unzip temp/MacOS/`ls temp/MacOS/` -d temp diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index e158aaf9..da57197f 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -42,12 +42,12 @@ jobs: - name: Install pybind11 run: cd /tmp/pybind11 && sudo make install - - name: Download SOFA nightly build + - name: Download SOFA v20.12.02 run: | curl --output sofa.zip -L \ - https://ci.inria.fr/sofa-ci-dev/job/nightly-generate-binaries-v20.12/lastSuccessfulBuild/CI_SCOPE=binaries_minimal/artifact/Linux/*zip*/Linux.zip + https://ci.inria.fr/sofa-ci-dev/job/nightly-generate-binaries/CI_SCOPE=binaries_minimal/309/artifact/Linux/*zip*/Linux.zip - - name: Install SOFA nightly build + - name: Install SOFA v20.12.02 run: | sudo unzip sofa.zip -d temp sudo unzip temp/Linux/`ls temp/Linux/` -d temp @@ -120,12 +120,12 @@ jobs: sudo apt install -qq libboost-all-dev python3 -m pip install numpy - - name: Download SOFA nightly build + - name: Download SOFA v20.12.02 run: | curl --output sofa.zip -L \ - https://ci.inria.fr/sofa-ci-dev/job/nightly-generate-binaries-v20.12/lastSuccessfulBuild/CI_SCOPE=binaries_minimal/artifact/Linux/*zip*/Linux.zip + https://ci.inria.fr/sofa-ci-dev/job/nightly-generate-binaries/CI_SCOPE=binaries_minimal/309/artifact/Linux/*zip*/Linux.zip - - name: Install SOFA nightly build + - name: Install SOFA v20.12.02 run: | sudo unzip sofa.zip -d temp sudo unzip temp/Linux/`ls temp/Linux/` -d temp From 31dc4822311e7341c0758e5096c385d933fe5b5b Mon Sep 17 00:00:00 2001 From: Guillaume Paran Date: Wed, 31 Mar 2021 17:41:51 +0200 Subject: [PATCH 9/9] [SofaGui] FIX qt.conf.h include depends on SofaGuiQt availability --- bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp b/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp index f36daff3..78bc1a5a 100644 --- a/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp +++ b/bindings/SofaGui/src/SofaPython3/SofaGui/Module_SofaGui.cpp @@ -26,7 +26,10 @@ #include #include using sofa::helper::system::FileSystem; + +#if SOFAGUI_HAVE_SOFAGUIQT #include +#endif // SOFAGUI_HAVE_SOFAGUIQT #include "Binding_BaseGui.h" #include "Binding_GUIManager.h" @@ -60,6 +63,7 @@ PYBIND11_MODULE(Gui, m) { :members: )doc"; +#if SOFAGUI_HAVE_SOFAGUIQT std::string sofaPrefixAbsolute = sofa::helper::Utils::getSofaPathPrefix(); std::string inputFilepath = FileSystem::cleanPath(sofaPrefixAbsolute + "/bin/qt.conf"); bool success = sofa::gui::qt::loadQtConfWithCustomPrefix(inputFilepath, sofaPrefixAbsolute); @@ -77,6 +81,7 @@ PYBIND11_MODULE(Gui, m) { } std::cout << std::endl; } +#endif // SOFAGUI_HAVE_SOFAGUIQT // This is needed to make sure the GuiMain library (libSofaGuiMain.so) is correctly // linked since the GUIs are statically created during the load of the library.