From patchwork Thu Feb 20 16:57:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 2864 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 47903625E5 for ; Thu, 20 Feb 2020 17:57:09 +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 D5BDEE7C; Thu, 20 Feb 2020 17:57:08 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1582217829; bh=kovIyEthjZxiQOgTA2fBWlo3ens78DeTuxlESMRYWMU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=u9WWJDXLN8o+HtdoYIO8Po7KMZoJ6YgIaMa1Ph5pxyMMo/sOu/2F/ZQAHKKLNI9EH dHr5YRw18mLaXVKg3XjEPTgkwdqIPmJ6aHXvN+huVaouu4taM7K2OMwB/+UC9cKJH2 J9/VOB5cWQjbQLA62YrqXmLBIdYw/9YBTKOpa7U4= From: Kieran Bingham To: libcamera devel 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 Subject: [libcamera-devel] [PATCH v3 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: Thu, 20 Feb 2020 16:57:10 -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 ... --- src/libcamera/ipa_manager.cpp | 46 ++++++++++++++++++++++++++++++++++- src/libcamera/meson.build | 6 +++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp index 3b1d4c0b295e..e60bf3dabebe 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,30 @@ * \brief Image Processing Algorithm module manager */ +static bool isLibcameraInstalled() +{ + extern ElfW(Dyn) _DYNAMIC[]; + /* DT_RUNPATH (DT_RPATH on musl) 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; + int ret; + + /* look up our own symbol. */ + ret = dladdr(reinterpret_cast(libcameraPath), &info); + if (ret == 0) + return nullptr; + + return info.dli_fname; +} + namespace libcamera { LOG_DEFINE_CATEGORY(IPAManager) @@ -108,7 +135,24 @@ 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. + */ + 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. */ ret = addDir(IPA_MODULE_DIR); if (ret > 0) ipaCount += ret; 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],