From patchwork Fri Feb 21 16:31:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 2867 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0146D6262D for ; Fri, 21 Feb 2020 17:31:35 +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 8494EA53; Fri, 21 Feb 2020 17:31:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582302694; bh=o9PQFCR1f94r3LacThxrHefONDhTKBExmHz6YKNo/r0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C5nAkQasskB8+PpShxgxpwBVxCfSq3bMQc6wBLv7dAjTssABlq378k9+vAuxyKkPC Sod5f+9FvyG7XQHWu2z3xkecv7hWh/9KSvtThbmQnS0RIzU2Fv6G03jTWUaiZQC45a W/ODDwcwlP1KluRHgYKBmNav58lFtZv/xyMNj5KY= From: Kieran Bingham To: libcamera devel Date: Fri, 21 Feb 2020 16:31:25 +0000 Message-Id: <20200221163130.4791-2-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 1/6] libcamera: utils: Add a C++ dirname implementation 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:35 -0000 Provide a std::string based implementation which conforms to the behaviour of the dirname() fucntion defined by POSIX. Tests are added to cover expected corner cases of the implementation. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/libcamera/include/utils.h | 1 + src/libcamera/utils.cpp | 48 +++++++++++++++++++++++++++++++ test/utils.cpp | 54 +++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/src/libcamera/include/utils.h b/src/libcamera/include/utils.h index 080ea6614de0..940597760ee2 100644 --- a/src/libcamera/include/utils.h +++ b/src/libcamera/include/utils.h @@ -33,6 +33,7 @@ namespace utils { const char *basename(const char *path); char *secure_getenv(const char *name); +std::string dirname(const std::string &path); template unsigned int set_overlap(InputIt1 first1, InputIt1 last1, diff --git a/src/libcamera/utils.cpp b/src/libcamera/utils.cpp index 453e3b3b5995..f566e88cec5b 100644 --- a/src/libcamera/utils.cpp +++ b/src/libcamera/utils.cpp @@ -70,6 +70,54 @@ char *secure_getenv(const char *name) #endif } +/** + * \brief Identify the dirname portion of a path + * \param[in] path The full path to parse + * + * This function conforms with the behaviour of the %dirname() function as + * defined by POSIX. + * + * \return A string of the directory component of the path + */ +std::string dirname(const std::string &path) +{ + if (path.empty()) + return "."; + + /* + * Skip all trailing slashes. If the path is only made of slashes, + * return "/". + */ + size_t pos = path.size() - 1; + while (path[pos] == '/') { + if (!pos) + return "/"; + pos--; + } + + /* + * Find the previous slash. If the path contains no non-trailing slash, + * return ".". + */ + while (path[pos] != '/') { + if (!pos) + return "."; + pos--; + } + + /* + * Return the directory name up to (but not including) any trailing + * slash. If this would result in an empty string, return "/". + */ + while (path[pos] == '/') { + if (!pos) + return "/"; + pos--; + } + + return path.substr(0, pos + 1); +} + /** * \fn libcamera::utils::set_overlap(InputIt1 first1, InputIt1 last1, * InputIt2 first2, InputIt2 last2) diff --git a/test/utils.cpp b/test/utils.cpp index db1fbdde847d..e4184e39ce32 100644 --- a/test/utils.cpp +++ b/test/utils.cpp @@ -19,6 +19,56 @@ using namespace libcamera; class UtilsTest : public Test { protected: + int testDirname() + { + std::vector paths = { + "", + "///", + "/bin", + "/usr/bin", + "//etc////", + "//tmp//d//", + "current_file", + "./current_file", + "./current_dir/", + "current_dir/", + }; + + std::vector expected = { + ".", + "/", + "/", + "/usr", + "/", + "//tmp", + ".", + ".", + ".", + ".", + }; + + std::vector results; + + for (const auto &path : paths) + results.push_back(utils::dirname(path)); + + if (results != expected) { + cerr << "utils::dirname() tests failed" << endl; + + cerr << "expected: " << endl; + for (const auto &path : expected) + cerr << " " << path << endl; + + cerr << "results: " << endl; + for (const auto &path : results) + cerr << " " << path << endl; + + return TestFail; + } + + return 0; + } + int run() { /* utils::hex() test. */ @@ -71,6 +121,10 @@ protected: return TestFail; } + /* utils::dirname() tests. */ + if (testDirname()) + return TestFail; + return TestPass; } }; From patchwork Fri Feb 21 16:31:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 2868 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5C3A96262D for ; Fri, 21 Feb 2020 17:31:35 +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 D755CB23; Fri, 21 Feb 2020 17:31:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582302695; bh=XxkNMJZmSBRgdZ0qfVdOTG9gKZv3YStnYPFUWkZaM8g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A/EyeKwLSmF+l6OD4aQKcmLoKfPW6mJHiyH8LtnlIUnWwLpHVh90cojzapStPVRMI FXzI+YZiuK3CHaUVKQcJAKUZEa+B6D3+HKMRGD3bk9ZUfMTWItS1hiuDDeZNvFTkjo cZl9Ql0Bw/HPJs6gfzFQCC2fAHG/sUQ6nbhdx+us= From: Kieran Bingham To: libcamera devel Date: Fri, 21 Feb 2020 16:31:26 +0000 Message-Id: <20200221163130.4791-3-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 2/6] libcamera: ipa_manager: Re-arrange IPA precedence 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:35 -0000 Setting a user environment path in LIBCAMERA_IPA_MODULE_PATH should take precedence over the system loading locations. Adjust the IPA search orders accordingly. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/libcamera/ipa_manager.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp index 4ffbdd712ac2..7f0a5d58749b 100644 --- a/src/libcamera/ipa_manager.cpp +++ b/src/libcamera/ipa_manager.cpp @@ -98,31 +98,31 @@ IPAManager::IPAManager() unsigned int ipaCount = 0; int ret; - ret = addDir(IPA_MODULE_DIR); - if (ret > 0) - ipaCount += ret; - + /* User-specified paths take precedence. */ const char *modulePaths = utils::secure_getenv("LIBCAMERA_IPA_MODULE_PATH"); - if (!modulePaths) { + if (modulePaths) { + for (const auto &dir : utils::split(modulePaths, ":")) { + if (dir.empty()) + continue; + + int ret = addDir(dir.c_str()); + if (ret > 0) + ipaCount += ret; + } + if (!ipaCount) LOG(IPAManager, Warning) - << "No IPA found in '" IPA_MODULE_DIR "'"; - return; + << "No IPA found in '" << modulePaths << "'"; } - for (const auto &dir : utils::split(modulePaths, ":")) { - if (dir.empty()) - continue; - - int ret = addDir(dir.c_str()); - if (ret > 0) - ipaCount += ret; - } + /* Load IPAs from the installed system path. */ + ret = addDir(IPA_MODULE_DIR); + if (ret > 0) + ipaCount += ret; if (!ipaCount) LOG(IPAManager, Warning) - << "No IPA found in '" IPA_MODULE_DIR "' and '" - << modulePaths << "'"; + << "No IPA found in '" IPA_MODULE_DIR "'"; } IPAManager::~IPAManager() From patchwork Fri Feb 21 16:31:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 2869 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 A79EE6262D for ; Fri, 21 Feb 2020 17:31:35 +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 4635E563; 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=pVUnLAeSR4c2y/LqcBY+eCCiMfX6Fn7svc8KfzAGo1Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kCR5PH18Cb1AjzxFP/HZxhIjbBG35dssvHTxdRGisDeJrT2jszGTdj0q7RHNON/8z bhE7w54sTcBX/U8QiNtoAihBNHuNK+lbltegEohd7TYbEDhWP2JBDw1M59y63gQqn9 1eHLuQM3QGiuO0Sc36FJScvgTXBxEe84R/65P0AM= From: Kieran Bingham To: libcamera devel Date: Fri, 21 Feb 2020 16:31:27 +0000 Message-Id: <20200221163130.4791-4-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 3/6] libcamera: ipa_manager: Simplify addDir() usage 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:35 -0000 The addDir call only returns an error if it can't open the directory. Callers only care about the number of modules added, and discard any error information. Simplify the return value and calling code by returning an unsigned int of the number of modules loaded. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/libcamera/include/ipa_manager.h | 2 +- src/libcamera/ipa_manager.cpp | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/libcamera/include/ipa_manager.h b/src/libcamera/include/ipa_manager.h index 126f8babbc8f..f13a93d74498 100644 --- a/src/libcamera/include/ipa_manager.h +++ b/src/libcamera/include/ipa_manager.h @@ -32,7 +32,7 @@ private: IPAManager(); ~IPAManager(); - int addDir(const char *libDir); + unsigned int addDir(const char *libDir); }; } /* namespace libcamera */ diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp index 7f0a5d58749b..90dd30030dcb 100644 --- a/src/libcamera/ipa_manager.cpp +++ b/src/libcamera/ipa_manager.cpp @@ -96,7 +96,6 @@ LOG_DEFINE_CATEGORY(IPAManager) IPAManager::IPAManager() { unsigned int ipaCount = 0; - int ret; /* User-specified paths take precedence. */ const char *modulePaths = utils::secure_getenv("LIBCAMERA_IPA_MODULE_PATH"); @@ -105,9 +104,7 @@ IPAManager::IPAManager() if (dir.empty()) continue; - int ret = addDir(dir.c_str()); - if (ret > 0) - ipaCount += ret; + ipaCount += addDir(dir.c_str()); } if (!ipaCount) @@ -116,9 +113,7 @@ IPAManager::IPAManager() } /* Load IPAs from the installed system path. */ - ret = addDir(IPA_MODULE_DIR); - if (ret > 0) - ipaCount += ret; + ipaCount += addDir(IPA_MODULE_DIR); if (!ipaCount) LOG(IPAManager, Warning) @@ -153,17 +148,16 @@ IPAManager *IPAManager::instance() * 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 + * \return Number of modules loaded by this call */ -int IPAManager::addDir(const char *libDir) +unsigned int IPAManager::addDir(const char *libDir) { struct dirent *ent; DIR *dir; dir = opendir(libDir); if (!dir) - return -errno; + return 0; std::vector paths; while ((ent = readdir(dir)) != nullptr) { 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++; From patchwork Fri Feb 21 16:31:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 2871 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5E0856262D 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 EBECFB23; 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=1582302696; bh=nV9nlzS1m+FlQoVFxKnDgltExk3LCkF+/7RziXIrRyI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KxmY/gxFjTjMNcAdYYy40kI6AMTRaAAGK3ghwTXc5Lkm9kqOeaRtUBjNywzpBEA0I M2kp8WW9ttE/PeTkc3aomJT4xgDotl3Lk/RHmokpyfPN4mJkoPlgBHIeM8kwejLMUU 2wFYK9u9+ZYgEDncePSz0oBGuQUypyTjISyypkYE= From: Kieran Bingham To: libcamera devel Date: Fri, 21 Feb 2020 16:31:29 +0000 Message-Id: <20200221163130.4791-6-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 5/6] libcamera: ipa_manager: Search for IPA libraries in build tree 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 When libcamera is built and tested (or used at all) before installing to the configured prefix path, it will be unable to locate the IPA binaries, or IPA binaries previously installed in the system paths may be incorrect to load. Utilise the build_rpath dynamic tag which is stripped out by meson at install time to determine at runtime if the library currently executing has been installed or not. When not installed and running from a build tree, identify the location of that tree by finding the path of the active libcamera.so itself, and from that point add a relative path to be able to load the most recently built IPA modules. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- v2: - Move get_runpath to ipa_manager.c : libcamera::elfRunPath() - Minor fixes - Squash elfRunPath() into this patch v3: - Full rework. It's just all different :-) - Maybe this one is going to cut it ... v4: - rebase and cleanup --- src/libcamera/ipa_manager.cpp | 52 ++++++++++++++++++++++++++++++++++- src/libcamera/meson.build | 6 ++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp index de99a0bc3ce1..a5f2707f6788 100644 --- a/src/libcamera/ipa_manager.cpp +++ b/src/libcamera/ipa_manager.cpp @@ -9,6 +9,9 @@ #include #include +#include +#include +#include #include #include @@ -24,6 +27,35 @@ * \brief Image Processing Algorithm module manager */ +static bool isLibcameraInstalled() +{ + /* musl doesn't declare _DYNAMIC in link.h, declare it manually. */ + extern ElfW(Dyn) _DYNAMIC[]; + + /* + * DT_RUNPATH (DT_RPATH when the linker uses old dtags) is removed on + * install. + */ + for (const ElfW(Dyn) *dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn) { + if (dyn->d_tag == DT_RUNPATH || dyn->d_tag == DT_RPATH) + return false; + } + + return true; +} + +static const char *libcameraPath() +{ + Dl_info info; + + /* Look up our own symbol. */ + int ret = dladdr(reinterpret_cast(libcameraPath), &info); + if (ret == 0) + return nullptr; + + return info.dli_fname; +} + namespace libcamera { LOG_DEFINE_CATEGORY(IPAManager) @@ -112,7 +144,25 @@ IPAManager::IPAManager() << "No IPA found in '" << modulePaths << "'"; } - /* Load IPAs from the installed system path. */ + /* + * When libcamera is used before it is installed, load IPAs from the + * same build directory as the libcamera library itself. This requires + * identifying the path of the libcamera.so, and referencing a relative + * path for the IPA from that point. We need to recurse one level of + * sub-directories to match the build tree. + */ + if (!isLibcameraInstalled()) { + std::string ipaBuildPath = utils::dirname(libcameraPath()) + "/../ipa"; + constexpr int maxDepth = 1; + + LOG(IPAManager, Info) + << "libcamera is not installed. Adding '" + << ipaBuildPath << "' to the IPA search path"; + + ipaCount += addDir(ipaBuildPath.c_str(), maxDepth); + } + + /* Finally try to load IPAs from the installed system path. */ ipaCount += addDir(IPA_MODULE_DIR); if (!ipaCount) diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 1e5b54b34078..88658ac563f7 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -107,11 +107,17 @@ if get_option('android') libcamera_link_with += android_camera_metadata endif +# We add '/' to the build_rpath as a 'safe' path to act as a boolean flag. +# The build_rpath is stripped at install time by meson, so we determine at +# runtime if the library is running from an installed location by checking +# for the presence or abscence of the dynamic tag. + libcamera = shared_library('camera', libcamera_sources, install : true, link_with : libcamera_link_with, include_directories : includes, + build_rpath : '/', dependencies : libcamera_deps) libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_ipa_api, libcamera_h], From patchwork Fri Feb 21 16:31:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 2872 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B8CCD6262D 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 48FC6563; Fri, 21 Feb 2020 17:31:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582302696; bh=ZBPbvyQpClEJshbj23iwbTuZN2upgaTObiY8xHIvp6c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CQP2OR7sByPcwGwB7eqhR7IpAIWQ3xQT7Tg8Aw6ak/oOksvW8sL+ZRhA4CQPEs3Xy 8C70IQXvE4juJxu+bKvQymyyzgU7rK/JUdEz1sh4umtw4n+JcsymEdnj79fKtiJjRd JalMpr3F0fG+KwzEPlNELeXW3uav5yhPdQ0picyk= From: Kieran Bingham To: libcamera devel Date: Fri, 21 Feb 2020 16:31:30 +0000 Message-Id: <20200221163130.4791-7-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 6/6] tests: Remove IPA_MODULE_PATH environment variable 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 The tests declare a hard-coded LIBCAMERA_IPA_MODULE_PATH to allow tests to run from the test-suite. This requires tests to be run only from the root of the build directory, otherwise (for example, by running in their local directory) they will not be able to correctly locate the IPA modules. Now that the build path for the IPA manager is determined at runtime we can remove the redundant setting of the LIBCAMERA_IPA_MODULE_PATH for tests. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- test/libtest/test.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/libtest/test.cpp b/test/libtest/test.cpp index 333d2160e276..6cd3fbe6df06 100644 --- a/test/libtest/test.cpp +++ b/test/libtest/test.cpp @@ -21,10 +21,6 @@ int Test::execute() { int ret; - ret = setenv("LIBCAMERA_IPA_MODULE_PATH", "src/ipa", 1); - if (ret) - return errno; - ret = setenv("LIBCAMERA_IPA_PROXY_PATH", "src/libcamera/proxy/worker", 1); if (ret) return errno;