[libcamera-devel] [RFC PATCH 6/8] libcamera: Add configuration interface

Jacopo Mondi jacopo at jmondi.org
Wed Nov 25 09:52:57 CET 2020


Hi Kieran,

On Mon, Nov 23, 2020 at 04:43:17PM +0000, Kieran Bingham wrote:
> Provide an interface to support reading configuration files.
>
> Initial support is included for JSON formatted files, but extending this
> with other configuration file formats is not excluded.
>
> Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> ---
>  README.rst                                 |  2 +-
>  include/libcamera/internal/configuration.h | 37 +++++++++
>  src/libcamera/configuration.cpp            | 91 ++++++++++++++++++++++
>  src/libcamera/meson.build                  |  1 +
>  4 files changed, 130 insertions(+), 1 deletion(-)
>  create mode 100644 include/libcamera/internal/configuration.h
>  create mode 100644 src/libcamera/configuration.cpp
>
> diff --git a/README.rst b/README.rst
> index 251291b77c62..c09e262fcc43 100644
> --- a/README.rst
> +++ b/README.rst
> @@ -58,7 +58,7 @@ Meson Build system: [required]
>              pip3 install --user --upgrade meson
>
>  for the libcamera core: [required]
> -        python3-yaml python3-ply python3-jinja2
> +        python3-yaml python3-ply python3-jinja2 nlohmann-json3-dev

First question I have is about the dependency on this package.

I have no real reasons to doubt about the availability of a packaged
version in most linux distro, nor about their stability and update
rate. It might be that projects named after a single person always
sound fragile to me, might be the rather low bus factor :)

Joking aside this seems to be packaged in most distros
https://repology.org/project/nlohmann-json/versions
with rather different versions (3.9.1 on Arch, 2.1.1 on Ubuntu 18.04
which is an LTS if I'm not mistaken).

There are notable exception though, in example Linux Mint.

In ChromiumOS R87 I don't see it packaged, my equery skills are very
low so I might have missed it.

The real question is:
- Are we happy to have this as externally packaged dependency ?

If I look at the Arch package content:
https://www.archlinux.org/packages/community/any/nlohmann-json/files/

This seems to be an header-only library. I wonder if we should not
rope it in during the build. There seems to be built-in support in
meson for that:
https://github.com/nlohmann/json#package-managers
https://wrapdb.mesonbuild.com/nlohmann_json

Or include ourselves a version of the library in our source tree,
which opens a different question: how do we feel about distributing MIT
licensed code ? It should be no issue, but IANAL so it's better to
give this a thought.

Thanks
  j

>
>  for IPA module signing: [required]
>          libgnutls28-dev openssl
> diff --git a/include/libcamera/internal/configuration.h b/include/libcamera/internal/configuration.h
> new file mode 100644
> index 000000000000..a89732f0210f
> --- /dev/null
> +++ b/include/libcamera/internal/configuration.h
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2020, Google Inc.
> + *
> + * configuration.h - Parsing configuration files
> + */
> +#ifndef __LIBCAMERA_INTERNAL_CONFIGURATION_H__
> +#define __LIBCAMERA_INTERNAL_CONFIGURATION_H__
> +
> +#include <fstream>
> +#include <string>
> +
> +/* https://nlohmann.github.io/json/home/exceptions/#switch-off-exceptions */
> +#define JSON_NOEXCEPTION 1
> +#include <nlohmann/json.hpp>
> +
> +using json = nlohmann::json;
> +
> +namespace libcamera {
> +
> +class Configuration
> +{
> +public:
> +	int open(std::string filename);
> +
> +	json &data() { return json_; }
> +
> +private:
> +	std::string findFile(std::string filename);
> +
> +	json json_;
> +};
> +
> +} /* namespace libcamera */
> +
> +#endif /* __LIBCAMERA_INTERNAL_CONFIGURATION_H__ */
> +
> diff --git a/src/libcamera/configuration.cpp b/src/libcamera/configuration.cpp
> new file mode 100644
> index 000000000000..f849088bbc45
> --- /dev/null
> +++ b/src/libcamera/configuration.cpp
> @@ -0,0 +1,91 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2020, Google Inc.
> + *
> + * configuration.cpp - Parsing configuration files
> + */
> +#include "libcamera/internal/configuration.h"
> +
> +#include "libcamera/internal/file.h"
> +#include "libcamera/internal/log.h"
> +#include "libcamera/internal/utils.h"
> +
> +#include <iostream>
> +#include <stdlib.h>
> +
> +/**
> + * \file configuration.h
> + * \brief Read interface for configuration files
> + */
> +
> +namespace libcamera {
> +
> +LOG_DEFINE_CATEGORY(Configuration)
> +
> +/*
> + * Configuration files can be stored in system paths, which are identified
> + * through the build configuration.
> + *
> + * However, when running uninstalled - the source location takes precedence.
> + */
> +std::string Configuration::findFile(std::string filename)
> +{
> +	static std::array<std::string, 2> searchPaths = {
> +		LIBCAMERA_SYSCONF_DIR,
> +		LIBCAMERA_DATA_DIR,
> +	};
> +
> +	std::string root = utils::libcameraSourcePath();
> +	if (!root.empty()) {
> +		std::string configurationPath = root + "data/" + filename;
> +
> +		if (File::exists(configurationPath))
> +			return configurationPath;
> +	}
> +
> +	for (std::string &path : searchPaths) {
> +		std::string configurationPath = path + "/" + filename;
> +		if (File::exists(configurationPath))
> +			return configurationPath;
> +	}
> +
> +	return "";
> +}
> +
> +/**
> + * \brief Open and parse a configuration file.
> + *
> + * The filename will be searched for on the libcamera configuration and paths,
> + * and then parsed.
> + *
> + * Successfully parsed files will present the data contained therein through the
> + * json object exposed from data();
> + */
> +int Configuration::open(std::string filename)
> +{
> +	std::string data = findFile(filename);
> +	if (data.empty()) {
> +		LOG(Configuration, Warning)
> +			<< "file: \"" << filename
> +			<< "\" was not found.";
> +		return -ENOENT;
> +	}
> +
> +	LOG(Configuration, Debug) << "Reading configuration from " << data;
> +
> +	/* Parse with no error callbacks and exceptions disabled. */
> +	std::ifstream input(data);
> +	json j = json::parse(input, nullptr, false);
> +	if (j.is_discarded()) {
> +		LOG(Configuration, Error)
> +			<< "file: \"" << data
> +			<< "\" was not parsable.";
> +		return -EINVAL;
> +	}
> +
> +	json_ = std::move(j);
> +
> +	return 0;
> +}
> +
> +} /* namespace libcamera */
> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> index 387d5d88ecae..5d655c87a7a0 100644
> --- a/src/libcamera/meson.build
> +++ b/src/libcamera/meson.build
> @@ -9,6 +9,7 @@ libcamera_sources = files([
>      'camera_controls.cpp',
>      'camera_manager.cpp',
>      'camera_sensor.cpp',
> +    'configuration.cpp',
>      'controls.cpp',
>      'control_serializer.cpp',
>      'control_validator.cpp',
> --
> 2.25.1
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel


More information about the libcamera-devel mailing list