summaryrefslogtreecommitdiff
path: root/src/qcam/assets/feathericons/external-link.svg
AgeCommit message (Expand)Author
2020-02-14qcam: assets: Provide initial icon setKieran Bingham
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
/* 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 */