Move the utils functionality to the libcamera/base library. Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
140 lines
3.5 KiB
C++
140 lines
3.5 KiB
C++
/* 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. */
|
|
extern ElfW(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
|
|
*/
|
|
bool isLibcameraInstalled()
|
|
{
|
|
/*
|
|
* 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;
|
|
}
|
|
|
|
} /* 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())
|
|
return std::string();
|
|
|
|
Dl_info info;
|
|
|
|
/* Look up our own symbol. */
|
|
int ret = dladdr(reinterpret_cast<void *>(libcameraBuildPath), &info);
|
|
if (ret == 0)
|
|
return std::string();
|
|
|
|
std::string path = dirname(info.dli_fname) + "/../../";
|
|
|
|
char *real = realpath(path.c_str(), nullptr);
|
|
if (!real)
|
|
return std::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())
|
|
return std::string();
|
|
|
|
path += "source";
|
|
|
|
char *real = realpath(path.c_str(), nullptr);
|
|
if (!real)
|
|
return std::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)
|
|
return std::string();
|
|
|
|
return path + "/";
|
|
}
|
|
|
|
} /* namespace utils */
|
|
|
|
} /* namespace libcamera */
|