{"id":2864,"url":"https://patchwork.libcamera.org/api/patches/2864/?format=json","web_url":"https://patchwork.libcamera.org/patch/2864/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20200220165704.23600-6-kieran.bingham@ideasonboard.com>","date":"2020-02-20T16:57:03","name":"[libcamera-devel,v3,5/6] libcamera: ipa_manager: Search for IPA libraries in build tree","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"125474fc2d3a9f86d66f25ef47d2fb3a7dab92ac","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/?format=json","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/2864/mbox/","series":[{"id":688,"url":"https://patchwork.libcamera.org/api/series/688/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=688","date":"2020-02-20T16:56:58","name":"Support loading IPAs from the build tree","version":3,"mbox":"https://patchwork.libcamera.org/series/688/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/2864/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/2864/checks/","tags":{},"headers":{"Return-Path":"<kieran.bingham@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 47903625E5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 20 Feb 2020 17:57:09 +0100 (CET)","from localhost.localdomain\n\t(cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D5BDEE7C;\n\tThu, 20 Feb 2020 17:57:08 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1582217829;\n\tbh=kovIyEthjZxiQOgTA2fBWlo3ens78DeTuxlESMRYWMU=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=u9WWJDXLN8o+HtdoYIO8Po7KMZoJ6YgIaMa1Ph5pxyMMo/sOu/2F/ZQAHKKLNI9EH\n\tdHr5YRw18mLaXVKg3XjEPTgkwdqIPmJ6aHXvN+huVaouu4taM7K2OMwB/+UC9cKJH2\n\tJ9/VOB5cWQjbQLA62YrqXmLBIdYw/9YBTKOpa7U4=","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"libcamera devel <libcamera-devel@lists.libcamera.org>","Date":"Thu, 20 Feb 2020 16:57:03 +0000","Message-Id":"<20200220165704.23600-6-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","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH v3 5/6] libcamera: ipa_manager: Search for\n\tIPA libraries in build tree","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Thu, 20 Feb 2020 16:57:10 -0000"},"content":"When libcamera is built and tested (or used at all) before installing to\nthe configured prefix path, it will be unable to locate the IPA\nbinaries, or IPA binaries previously installed in the system paths may\nbe incorrect to load.\n\nUtilise the build_rpath dynamic tag which is stripped out by meson at\ninstall time to determine at runtime if the library currently executing\nhas been installed or not.\n\nWhen not installed and running from a build tree, identify the location\nof that tree by finding the path of the active libcamera.so itself, and\nfrom that point add a relative path to be able to load the most recently\nbuilt IPA modules.\n\nSigned-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n---\nv2:\n - Move get_runpath to ipa_manager.c : libcamera::elfRunPath()\n - Minor fixes\n - Squash elfRunPath() into this patch\n\nv3:\n - Full rework. It's just all different :-)\n - Maybe this one is going to cut it ...\n---\n src/libcamera/ipa_manager.cpp | 46 ++++++++++++++++++++++++++++++++++-\n src/libcamera/meson.build     |  6 +++++\n 2 files changed, 51 insertions(+), 1 deletion(-)","diff":"diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp\nindex 3b1d4c0b295e..e60bf3dabebe 100644\n--- a/src/libcamera/ipa_manager.cpp\n+++ b/src/libcamera/ipa_manager.cpp\n@@ -9,6 +9,9 @@\n \n #include <algorithm>\n #include <dirent.h>\n+#include <dlfcn.h>\n+#include <elf.h>\n+#include <link.h>\n #include <string.h>\n #include <sys/types.h>\n \n@@ -24,6 +27,30 @@\n  * \\brief Image Processing Algorithm module manager\n  */\n \n+static bool isLibcameraInstalled()\n+{\n+\textern ElfW(Dyn) _DYNAMIC[];\n+\t/* DT_RUNPATH (DT_RPATH on musl) is removed on install. */\n+\tfor (const ElfW(Dyn) *dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn)\n+\t\tif (dyn->d_tag == DT_RUNPATH || dyn->d_tag == DT_RPATH)\n+\t\t\treturn false;\n+\n+\treturn true;\n+}\n+\n+static const char *libcameraPath()\n+{\n+\tDl_info info;\n+\tint ret;\n+\n+\t/* look up our own symbol. */\n+\tret = dladdr(reinterpret_cast<void *>(libcameraPath), &info);\n+\tif (ret == 0)\n+\t\treturn nullptr;\n+\n+\treturn info.dli_fname;\n+}\n+\n namespace libcamera {\n \n LOG_DEFINE_CATEGORY(IPAManager)\n@@ -108,7 +135,24 @@ IPAManager::IPAManager()\n \t\t\t\t<< \"No IPA found in '\" << modulePaths << \"'\";\n \t}\n \n-\t/* Load IPAs from the installed system path. */\n+\t/*\n+\t * When libcamera is used before it is installed, load IPAs from the\n+\t * same build directory as the libcamera library itself. This requires\n+\t * identifying the path of the libcamera.so, and referencing a relative\n+\t * path for the IPA from that point.\n+\t */\n+\tif (!isLibcameraInstalled()) {\n+\t\tstd::string ipaBuildPath = utils::dirname(libcameraPath()) + \"/../ipa\";\n+\t\tconstexpr int maxDepth = 1;\n+\n+\t\tLOG(IPAManager, Info)\n+\t\t\t<< \"libcamera is not installed. Adding '\"\n+\t\t\t<< ipaBuildPath << \"' to the IPA search path\";\n+\n+\t\tipaCount += addDir(ipaBuildPath.c_str(), maxDepth);\n+\t}\n+\n+\t/* Finally try to load IPAs from the installed system path. */\n \tret = addDir(IPA_MODULE_DIR);\n \tif (ret > 0)\n \t\tipaCount += ret;\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex 1e5b54b34078..88658ac563f7 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -107,11 +107,17 @@ if get_option('android')\n     libcamera_link_with += android_camera_metadata\n endif\n \n+# We add '/' to the build_rpath as a 'safe' path to act as a boolean flag.\n+# The build_rpath is stripped at install time by meson, so we determine at\n+# runtime if the library is running from an installed location by checking\n+# for the presence or abscence of the dynamic tag.\n+\n libcamera = shared_library('camera',\n                            libcamera_sources,\n                            install : true,\n                            link_with : libcamera_link_with,\n                            include_directories : includes,\n+                           build_rpath : '/',\n                            dependencies : libcamera_deps)\n \n libcamera_dep = declare_dependency(sources : [libcamera_api, libcamera_ipa_api, libcamera_h],\n","prefixes":["libcamera-devel","v3","5/6"]}