/* SPDX-License-Identifier: LGPL-2.1-or-later *//* * Copyright (C) 2021, Google Inc. * * source_paths.cpp - Identify libcamera source and build paths */#include"libcamera/internal/source_paths.h"#include <dlfcn.h>#include <elf.h>#include <link.h>#include <stdlib.h>#include <sys/stat.h>#include <sys/types.h>#include <libcamera/base/utils.h>/** * \file source_paths.h * \brief Identify the build and source path of a not-yet-installed library *//* musl doesn't declare _DYNAMIC in link.h, declare it manually. */externElfW(Dyn) _DYNAMIC[];namespace libcamera {namespace{/** * \brief Check if libcamera is installed or not * * 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. * * \return True if libcamera is installed, false otherwise */boolisLibcameraInstalled(){/* * DT_RUNPATH (DT_RPATH when the linker uses old dtags) is removed on * install. */for(constElfW(Dyn) *dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn) {if(dyn->d_tag == DT_RUNPATH || dyn->d_tag == DT_RPATH)return false;}return true;}}/* namespace */namespace utils {/** * \brief Retrieve the path to the build directory * * During development, it is useful to run libcamera binaries directly from the * build directory without installing them. This function helps components that * need to locate resources in the build tree, such as IPA modules or IPA proxy * workers, by providing them with the path to the root of the build directory. * Callers can then use it to complement or override searches in system-wide * directories. * * If libcamera has been installed, the build directory path is not available * and this function returns an empty string. * * \return The path to the build directory if running from a build, or an empty * string otherwise */std::string libcameraBuildPath(){if(isLibcameraInstalled())returnstd::string();
Dl_info info;/* Look up our own symbol. */int ret =dladdr(reinterpret_cast<void*>(libcameraBuildPath), &info);if(ret ==0)returnstd::string();std::string path =dirname(info.dli_fname) +"/../../";char*real =realpath(path.c_str(),nullptr);if(!real)returnstd::string();
path = real;free(real);return path +"/";}/** * \brief Retrieve the path to the source directory * * During development, it is useful to run libcamera binaries directly from the * build directory without installing them. This function helps components that * need to locate resources in the source tree, such as IPA configuration * files, by providing them with the path to the root of the source directory. * Callers can then use it to complement or override searches in system-wide * directories. * * If libcamera has been installed, the source directory path is not available * and this function returns an empty string. * * \return The path to the source directory if running from a build directory, * or an empty string otherwise */std::string libcameraSourcePath(){std::string path =libcameraBuildPath();if(path.empty())returnstd::string();
path +="source";char*real =realpath(path.c_str(),nullptr);if(!real)returnstd::string();
path = real;free(real);struct stat statbuf;int ret =stat(path.c_str(), &statbuf);if(ret <0|| (statbuf.st_mode & S_IFMT) != S_IFDIR)returnstd::string();return path +"/";}}/* namespace utils */}/* namespace libcamera */