[libcamera-devel] [PATCH v3 3/6] libcamera: ipa_manager: Allow recursive parsing
Kieran Bingham
kieran.bingham at ideasonboard.com
Thu Feb 20 17:57:01 CET 2020
Provide an optional means to recurse into subdirectories to search for IPA
libraries. This allows IPAs contained within their own build directory
to be resolved when loading from a non-installed build.
Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
---
src/libcamera/include/ipa_manager.h | 6 ++-
src/libcamera/ipa_manager.cpp | 69 ++++++++++++++++++++++-------
2 files changed, 58 insertions(+), 17 deletions(-)
diff --git a/src/libcamera/include/ipa_manager.h b/src/libcamera/include/ipa_manager.h
index 94d35d9062e4..5dca2c2a7d8d 100644
--- a/src/libcamera/include/ipa_manager.h
+++ b/src/libcamera/include/ipa_manager.h
@@ -32,8 +32,10 @@ private:
IPAManager();
~IPAManager();
- int addDir(const char *libDir);
- int addPath(const char *path);
+ int parseDir(const char *libDir, std::vector<std::string> &files,
+ unsigned int maxDepth);
+ int addDir(const char *libDir, unsigned int maxDepth = 0);
+ int addPath(const char *path, unsigned int maxDepth = 0);
};
} /* namespace libcamera */
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index d87f2221b00b..c30b4555290f 100644
--- a/src/libcamera/ipa_manager.cpp
+++ b/src/libcamera/ipa_manager.cpp
@@ -140,16 +140,20 @@ 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 IPA modules
+ * \param[in] files A vector of paths to shared object library files
+ * \param[in] maxDepth The maximum depth of sub-directories to parse
*
- * 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
+ * subdirectories no further than the depth specified by \a maxDepth.
*
- * \return Number of modules loaded by this call, or a negative error code
- * otherwise
+ * Discovered shared objects are added to the files vector.
+ *
+ * \return 0 on success or a negative error code otherwise
*/
-int IPAManager::addDir(const char *libDir)
+int IPAManager::parseDir(const char *libDir, std::vector<std::string> &files,
+ unsigned int maxDepth)
{
struct dirent *ent;
DIR *dir;
@@ -158,30 +162,64 @@ int IPAManager::addDir(const char *libDir)
if (!dir)
return -errno;
- 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(), files, maxDepth - 1);
+
+ 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);
+ return 0;
+}
+
+/**
+ * \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 parse
+ *
+ * This method tries to create an IPAModule instance for every shared object
+ * found in \a libDir, and skips invalid IPA modules.
+ *
+ * \return Number of modules loaded by this call, or a negative error code
+ * otherwise
+ */
+int IPAManager::addDir(const char *libDir, unsigned int maxDepth)
+{
+ std::vector<std::string> files;
+
+ int ret = parseDir(libDir, files, maxDepth);
+ if (ret < 0)
+ return ret;
+
/* 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++;
@@ -193,6 +231,7 @@ int IPAManager::addDir(const char *libDir)
/**
* \brief Load IPA modules from a search path
* \param[in] path The colon-separated list of directories to load IPA modules from
+ * \param[in] maxDepth The maximum number of sub-directories to parse
*
* This method tries to create an IPAModule instance for every shared object
* found in the directories listed in \a path.
@@ -200,7 +239,7 @@ int IPAManager::addDir(const char *libDir)
* \return Number of modules loaded by this call, or a negative error code
* otherwise
*/
-int IPAManager::addPath(const char *path)
+int IPAManager::addPath(const char *path, unsigned int maxDepth)
{
int ipaCount = 0;
@@ -208,7 +247,7 @@ int IPAManager::addPath(const char *path)
if (dir.empty())
continue;
- int ret = addDir(dir.c_str());
+ int ret = addDir(dir.c_str(), maxDepth);
if (ret > 0)
ipaCount += ret;
}
--
2.20.1
More information about the libcamera-devel
mailing list