From patchwork Fri Feb 21 16:31:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 2870 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0EF716262D for ; Fri, 21 Feb 2020 17:31:36 +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 935F0A53; Fri, 21 Feb 2020 17:31:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582302695; bh=PyR3DmcvjFHkQoIbXGHyyMsI6ZTY/VMyqNsiGYry+6U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=khxstdAHg8Xzqq9owYhRsWMDeW8mq46FOT3RVON9gJYx7llMNIRUo10EwT69mS7VZ DowTBmRq3oI2c6WPjbBxjzY9kshasQtv6rRwgjW70USttywj1oLleUkzw8maAja3Xa magC/dGCv6FOXoin6kBL5MyMUfvQ17cHxEPCDTVs= From: Kieran Bingham To: libcamera devel Date: Fri, 21 Feb 2020 16:31:28 +0000 Message-Id: <20200221163130.4791-5-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200221163130.4791-1-kieran.bingham@ideasonboard.com> References: <20200221163130.4791-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 4/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: Fri, 21 Feb 2020 16:31:36 -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 found when loading from a non-installed build. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/libcamera/include/ipa_manager.h | 4 +- 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 f13a93d74498..467658e40ce9 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 &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 90dd30030dcb..de99a0bc3ce1 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 &files) { struct dirent *ent; DIR *dir; dir = opendir(libDir); if (!dir) - return 0; + return; - 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(), 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 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++;