From patchwork Thu Feb 20 16:57:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 2862 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A29F9625C1 for ; Thu, 20 Feb 2020 17:57:08 +0100 (CET) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1BAFC13C7; Thu, 20 Feb 2020 17:57:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582217828; bh=eCzZCVbPvJRe29BE5V9Smwp7Xg7gFtgIKdPaBqmAaBk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F5tZplKQTnEWtk9tOZufbdmuQGP6ilxnateEKbahBUIp5OrIgowdx8fbfXL19lCn+ zda1H+upNNTAhtK3HwjudolaUFHLfcdLU/5IzQQcFCZnla7sOmA3AjnTbq7Jwz0JUS M7bkSaqoMofDzR+PTHBv1o5PGWCD1ZhKUpf/Wq6E= From: Kieran Bingham To: libcamera devel Date: Thu, 20 Feb 2020 16:57:01 +0000 Message-Id: <20200220165704.23600-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200220165704.23600-1-kieran.bingham@ideasonboard.com> References: <20200220165704.23600-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 3/6] libcamera: ipa_manager: Allow recursive parsing X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Feb 2020 16:57:08 -0000 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 Reviewed-by: Laurent Pinchart --- 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 &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 &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 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 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; }