summaryrefslogtreecommitdiff
path: root/src/libcamera/ipa_manager.cpp
diff options
context:
space:
mode:
authorKieran Bingham <kieran.bingham@ideasonboard.com>2020-02-04 18:00:04 +0000
committerKieran Bingham <kieran.bingham@ideasonboard.com>2020-02-24 09:45:56 +0000
commit1d8ca53d581fb9e088ca2a91ca72788f32f7ec59 (patch)
tree33c78d1be5a09febf5ff931554570fa03a4de866 /src/libcamera/ipa_manager.cpp
parent417c4ae87e6963ca86f308b31793ef96cc33c71a (diff)
libcamera: ipa_manager: Search for IPA libraries in build tree
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 <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.cpp52
1 files changed, 51 insertions, 1 deletions
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index de99a0bc..238433dc 100644
--- a/src/libcamera/ipa_manager.cpp
+++ b/src/libcamera/ipa_manager.cpp
@@ -9,6 +9,9 @@
#include <algorithm>
#include <dirent.h>
+#include <dlfcn.h>
+#include <elf.h>
+#include <link.h>
#include <string.h>
#include <sys/types.h>
@@ -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 std::string libcameraPath()
+{
+ Dl_info info;
+
+ /* Look up our own symbol. */
+ int ret = dladdr(reinterpret_cast<void *>(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)