summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/ipa_manager.cpp52
-rw-r--r--src/libcamera/meson.build6
2 files changed, 57 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)
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 1e5b54b3..88658ac5 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],