diff options
author | Kieran Bingham <kieran.bingham@ideasonboard.com> | 2020-02-05 11:21:38 +0000 |
---|---|---|
committer | Kieran Bingham <kieran.bingham@ideasonboard.com> | 2020-02-24 09:36:52 +0000 |
commit | 417c4ae87e6963ca86f308b31793ef96cc33c71a (patch) | |
tree | 7d24d675abb08cc75297986b5e0a596a93b90515 | |
parent | 80d70e4fcf6c8aa92c3097414b90325e855bab6e (diff) |
libcamera: ipa_manager: Allow recursive parsing
Provide an optional means to recurse into subdirectories to search for IPA
libraries. This allows IPAs contained within their own build directory
to be found when loading from a non-installed build.
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r-- | src/libcamera/include/ipa_manager.h | 4 | ||||
-rw-r--r-- | src/libcamera/ipa_manager.cpp | 62 |
2 files changed, 52 insertions, 14 deletions
diff --git a/src/libcamera/include/ipa_manager.h b/src/libcamera/include/ipa_manager.h index f13a93d7..467658e4 100644 --- a/src/libcamera/include/ipa_manager.h +++ b/src/libcamera/include/ipa_manager.h @@ -32,7 +32,9 @@ private: IPAManager(); ~IPAManager(); - unsigned int addDir(const char *libDir); + void parseDir(const char *libDir, unsigned int maxDepth, + std::vector<std::string> &files); + unsigned int addDir(const char *libDir, unsigned int maxDepth = 0); }; } /* namespace libcamera */ diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp index 90dd3003..de99a0bc 100644 --- a/src/libcamera/ipa_manager.cpp +++ b/src/libcamera/ipa_manager.cpp @@ -142,47 +142,83 @@ IPAManager *IPAManager::instance() } /** - * \brief Load IPA modules from a directory - * \param[in] libDir directory to search for IPA modules + * \brief Identify shared library objects within a directory + * \param[in] libDir The directory to search for shared objects + * \param[in] maxDepth The maximum depth of sub-directories to parse + * \param[out] files A vector of paths to shared object library files * - * This method tries to create an IPAModule instance for every shared object - * found in \a libDir, and skips invalid IPA modules. + * Search a directory for .so files, allowing recursion down to sub-directories + * no further than the depth specified by \a maxDepth. * - * \return Number of modules loaded by this call + * Discovered shared objects are added to the \a files vector. */ -unsigned int IPAManager::addDir(const char *libDir) +void IPAManager::parseDir(const char *libDir, unsigned int maxDepth, + std::vector<std::string> &files) { struct dirent *ent; DIR *dir; dir = opendir(libDir); if (!dir) - return 0; + return; - std::vector<std::string> paths; while ((ent = readdir(dir)) != nullptr) { + if (ent->d_type == DT_DIR && maxDepth) { + if (strcmp(ent->d_name, ".") == 0 || + strcmp(ent->d_name, "..") == 0) + continue; + + std::string subdir = std::string(libDir) + "/" + ent->d_name; + + /* Recursion is limited to maxDepth. */ + parseDir(subdir.c_str(), maxDepth - 1, files); + + continue; + } + int offset = strlen(ent->d_name) - 3; if (offset < 0) continue; if (strcmp(&ent->d_name[offset], ".so")) continue; - paths.push_back(std::string(libDir) + "/" + ent->d_name); + files.push_back(std::string(libDir) + "/" + ent->d_name); } + closedir(dir); +} + +/** + * \brief Load IPA modules from a directory + * \param[in] libDir The directory to search for IPA modules + * \param[in] maxDepth The maximum depth of sub-directories to search + * + * This method tries to create an IPAModule instance for every shared object + * found in \a libDir, and skips invalid IPA modules. + * + * Sub-directories are searched up to a depth of \a maxDepth. A \a maxDepth + * value of 0 only searches the directory specified in \a libDir. + * + * \return Number of modules loaded by this call + */ +unsigned int IPAManager::addDir(const char *libDir, unsigned int maxDepth) +{ + std::vector<std::string> files; + + parseDir(libDir, maxDepth, files); /* Ensure a stable ordering of modules. */ - std::sort(paths.begin(), paths.end()); + std::sort(files.begin(), files.end()); unsigned int count = 0; - for (const std::string &path : paths) { - IPAModule *ipaModule = new IPAModule(path); + for (const std::string &file : files) { + IPAModule *ipaModule = new IPAModule(file); if (!ipaModule->isValid()) { delete ipaModule; continue; } - LOG(IPAManager, Debug) << "Loaded IPA module '" << path << "'"; + LOG(IPAManager, Debug) << "Loaded IPA module '" << file << "'"; modules_.push_back(ipaModule); count++; |