summaryrefslogtreecommitdiff
path: root/src/libcamera/ipa_manager.cpp
diff options
context:
space:
mode:
authorKieran Bingham <kieran.bingham@ideasonboard.com>2020-02-05 11:21:38 +0000
committerKieran Bingham <kieran.bingham@ideasonboard.com>2020-02-24 09:36:52 +0000
commit417c4ae87e6963ca86f308b31793ef96cc33c71a (patch)
tree7d24d675abb08cc75297986b5e0a596a93b90515 /src/libcamera/ipa_manager.cpp
parent80d70e4fcf6c8aa92c3097414b90325e855bab6e (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>
Diffstat (limited to 'src/libcamera/ipa_manager.cpp')
-rw-r--r--src/libcamera/ipa_manager.cpp62
1 files changed, 49 insertions, 13 deletions
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++;