diff --git a/src/Base/App.cpp b/src/Base/App.cpp index f61937909..885d88cee 100644 --- a/src/Base/App.cpp +++ b/src/Base/App.cpp @@ -104,6 +104,7 @@ bool isNoWindowMode = false; bool ctrl_c_pressed = false; bool exitRequested = false; vector additionalPathVariables; +vector pluginDirsAsPrefix; void onCtrl_C_Input(int) { @@ -222,7 +223,11 @@ App::Impl::Impl(App* self, int& argc, char** argv, const std::string& appName, c mout->setPendingMode(true); AppConfig::initialize(appName, organization); + pluginManager = PluginManager::instance(); + if(auto pluginPathList = getenv("CNOID_PLUGIN_PATH")){ + pluginManager->addPluginPathList(toUTF8(pluginPathList)); + } ext = nullptr; mainWindow = nullptr; @@ -317,7 +322,7 @@ void App::setIcon(const std::string& filename) void App::addPluginPath(const std::string& path) { if(!path.empty()){ - impl->pluginManager->addPluginPath(path); + impl->pluginManager->addPluginPathList(path); } } @@ -375,6 +380,10 @@ void App::Impl::initialize() optionManager->add_option( "--path-variable", additionalPathVariables, "Set a path variable in the format \"name=value\""); + + optionManager->add_option( + "--add-plugin-dir-as-prefix", pluginDirsAsPrefix, + "Add a plugin directory as an install path prefix"); mainWindow = MainWindow::initialize(appName, ext); @@ -545,6 +554,10 @@ int App::Impl::exec() doQuit = true; } } + + for(auto& prefix : pluginDirsAsPrefix){ + pluginManager->addPluginDirectoryAsPrefix(prefix); + } optionManager->processOptionsPhase1(); diff --git a/src/Base/App.h b/src/Base/App.h index 4bea695b1..a65b01156 100644 --- a/src/Base/App.h +++ b/src/Base/App.h @@ -27,7 +27,9 @@ class CNOID_EXPORT App ~App(); + [[deprecated("Use PluginManager::addPluginPathList")]] void addPluginPath(const std::string& path); + bool requirePluginToCustomizeApplication(const std::string& pluginName); // Optional setting diff --git a/src/Base/PluginManager.cpp b/src/Base/PluginManager.cpp index adf982846..22d4d64a6 100644 --- a/src/Base/PluginManager.cpp +++ b/src/Base/PluginManager.cpp @@ -100,7 +100,7 @@ class PluginManager::Impl MainMenu* mainMenu; string pluginDirectory; - vector pluginPaths; + vector pluginDirectories; QRegExp pluginNamePattern; vector allPluginInfos; @@ -121,7 +121,7 @@ class PluginManager::Impl LazyCaller unloadPluginsLater; LazyCaller reloadPluginsLater; - void addPluginPath(const std::string& path); + void addPluginDirectory(const std::string& directory, bool doMakeAbsolute); void loadPlugins(bool doActivation); void scanPluginFiles(const std::string& pathString, bool isUTF8, bool isRecursive); void loadScannedPluginFiles(bool doActivation); @@ -176,7 +176,7 @@ PluginManager::Impl::Impl() mout = MessageOut::master(); mainMenu = nullptr; - addPluginPath(cnoid::pluginDir()); + addPluginDirectory(cnoid::pluginDir(), false); pluginNamePattern.setPattern( QString(DLL_PREFIX) + "Cnoid(.+)Plugin" + DEBUG_SUFFIX + "\\." + DLL_EXTENSION); @@ -208,27 +208,73 @@ PluginManager::Impl::~Impl() /** - @param path semicolon or colon separeted path list. + @param pathList semicolon or colon separeted absolute path list. */ -void PluginManager::addPluginPath(const std::string& pathString) +void PluginManager::addPluginPathList(const std::string& pathList) { - for(auto& path : Tokenizer>(pathString, CharSeparator(PATH_DELIMITER))){ - impl->addPluginPath(path); + for(auto& dir : Tokenizer>(pathList, CharSeparator(PATH_DELIMITER))){ + impl->addPluginDirectory(dir, false); } } - -void PluginManager::Impl::addPluginPath(const std::string& path) + +void PluginManager::addPluginPath(const std::string& pathList) { - pluginPaths.push_back(path); + addPluginPathList(pathList); +} + + +void PluginManager::addPluginDirectory(const std::string& directory) +{ + impl->addPluginDirectory(directory, true); +} + + +void PluginManager::Impl::addPluginDirectory(const std::string& directory, bool doMakeAbsolute) +{ + string directoryFromUTF8; + if(doMakeAbsolute){ + directoryFromUTF8 = fromUTF8(directory); + filesystem::path path(directoryFromUTF8); + if(!path.is_absolute()){ + string absDirectory = filesystem::absolute(path).string(); + pluginDirectories.insert(pluginDirectories.begin(), toUTF8(absDirectory)); +#ifdef Q_OS_WIN32 + // Add the plugin directory to PATH + qputenv("PATH", format("{0};{1}", absDirectory, qgetenv("PATH")).c_str()); +#endif + return; + } + } + + pluginDirectories.insert(pluginDirectories.begin(), directory); #ifdef Q_OS_WIN32 // Add the plugin directory to PATH - qputenv("PATH", format("{0};{1}", fromUTF8(path), qgetenv("PATH")).c_str()); + if(directoryFromUTF8.empty()){ + directoryFromUTF8 = fromUTF8(directory); + } + qputenv("PATH", format("{0};{1}", directoryFromUTF8, qgetenv("PATH")).c_str()); #endif } +/** + @param directory the install prefix of the corresponding plugin module. +*/ +void PluginManager::addPluginDirectoryAsPrefix(const std::string& prefix) +{ + addPluginDirectory( + toUTF8((filesystem::path(fromUTF8(prefix)) / CNOID_PLUGIN_SUBDIR).string())); +} + + +const std::vector PluginManager::pluginDirectories() const +{ + return impl->pluginDirectories; +} + + bool PluginManager::isStartupLoadingDisabled() const { return impl->isStartupLoadingDisabled; @@ -252,8 +298,8 @@ void PluginManager::loadPlugins(bool doActivation) void PluginManager::Impl::loadPlugins(bool doActivation) { if(allPluginInfos.empty()){ // Not scanned yet - for(auto& path : pluginPaths){ - scanPluginFiles(path, true, false); + for(auto& dir : pluginDirectories){ + scanPluginFiles(dir, true, false); } } loadScannedPluginFiles(doActivation); @@ -776,7 +822,7 @@ int PluginManager::numPlugins() const } -const std::string& PluginManager::pluginPath(int index) const +const std::string& PluginManager::pluginFile(int index) const { return impl->allPluginInfos[index]->pathString; } diff --git a/src/Base/PluginManager.h b/src/Base/PluginManager.h index 1df247694..b8f47e798 100644 --- a/src/Base/PluginManager.h +++ b/src/Base/PluginManager.h @@ -1,11 +1,8 @@ -/** - @author Shin'ichiro Nakaoka -*/ - #ifndef CNOID_BASE_PLUGIN_MANAGER_H #define CNOID_BASE_PLUGIN_MANAGER_H #include +#include #include "exportdecl.h" namespace cnoid { @@ -19,7 +16,13 @@ class CNOID_EXPORT PluginManager ~PluginManager(); - void addPluginPath(const std::string& path); + void addPluginPathList(const std::string& pathList); + [[deprecated("Use addPluginPathList")]] + void addPluginPath(const std::string& pathList); + + void addPluginDirectory(const std::string& directory); + void addPluginDirectoryAsPrefix(const std::string& prefix); + const std::vector pluginDirectories() const; bool isStartupLoadingDisabled() const; void doStartupLoading(); void loadPlugins(bool doActivation); @@ -32,7 +35,7 @@ class CNOID_EXPORT PluginManager void flushMessagesTo(std::ostream& os); int numPlugins() const; - const std::string& pluginPath(int index) const; + const std::string& pluginFile(int index) const; const std::string& pluginName(int index) const; enum PluginStatus { NOT_LOADED, LOADED, ACTIVE, FINALIZED, UNLOADED, INVALID, CONFLICT }; diff --git a/src/Choreonoid/choreonoid.cpp b/src/Choreonoid/choreonoid.cpp index 9dc7d13ad..cecf3d492 100644 --- a/src/Choreonoid/choreonoid.cpp +++ b/src/Choreonoid/choreonoid.cpp @@ -6,8 +6,6 @@ */ #include -#include -#include using namespace cnoid; @@ -31,9 +29,6 @@ int main(int argc, char *argv[]) int execute(cnoid::App& app) { - if(auto pluginPath = getenv("CNOID_PLUGIN_PATH")){ - app.addPluginPath(toUTF8(pluginPath)); - } app.setBuiltinProject(":/Base/project/layout.cnoid"); return app.exec(); }