[{"id":1863,"web_url":"https://patchwork.libcamera.org/comment/1863/","msgid":"<20190611203237.GY5016@pendragon.ideasonboard.com>","date":"2019-06-11T20:32:37","subject":"Re: [libcamera-devel] [PATCH] libcamera: Auto generate version\n\tinformation","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Kieran,\n\nThank you for the patch.\n\nOn Tue, Jun 11, 2019 at 09:14:11PM +0100, Kieran Bingham wrote:\n> Generate a version string, and provide a global singleton object which\n> allows applications to interogate the current libcamera version\n> information.\n> \n> The version header is automatically updated by meson on each build.\n> The string roughly follows the semver [0] conventions of\n> major.minor.patch-label as a value.\n> \n> [0] https://semver.org/\n> \n> The utils/version-gen script will look for tags in the form vX.Y as\n> starting points for the version string. While the repository does not\n> have any matching tags, v0.0 will be assumed, resulting in versions with\n> both major and minor being set to '0', and the patch count resulting\n> from the number of patches in the history to that point.\n> \n> Finally, a uniquely identifying shortened checksum is provided from git:\n> \n> \tv0.0.509.c544\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  Documentation/conf.py         |  6 ++++--\n>  include/libcamera/meson.build |  1 +\n>  include/libcamera/version.h   | 23 ++++++++++++++++++++\n>  meson.build                   |  9 +++++++-\n>  src/libcamera/meson.build     |  1 +\n>  src/libcamera/version.cpp     | 40 +++++++++++++++++++++++++++++++++++\n>  utils/version-gen             | 36 +++++++++++++++++++++++++++++++\n>  version.h.in                  |  3 +++\n>  8 files changed, 116 insertions(+), 3 deletions(-)\n>  create mode 100644 include/libcamera/version.h\n>  create mode 100644 src/libcamera/version.cpp\n>  create mode 100755 utils/version-gen\n>  create mode 100644 version.h.in\n> \n> diff --git a/Documentation/conf.py b/Documentation/conf.py\n> index 970edf3d7298..e5980b98216d 100644\n> --- a/Documentation/conf.py\n> +++ b/Documentation/conf.py\n> @@ -23,10 +23,12 @@ project = 'libcamera'\n>  copyright = '2018-2019, The libcamera documentation authors'\n>  author = u'Kieran Bingham, Jacopo Mondi, Laurent Pinchart, Niklas Söderlund'\n>  \n> +# Vesion information is provided by the build environment.\n\ns/Vesion/Version/\n\n> +#\n>  # The short X.Y version\n> -version = ''\n> +# version = ''\n>  # The full version, including alpha/beta/rc tags\n> -release = '0.1'\n> +# release = '0.1'\n\nShould we just delete the version and release lines ?\n\n>  # -- General configuration ---------------------------------------------------\n> diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\n> index 1b86fdc7fca4..201832105457 100644\n> --- a/include/libcamera/meson.build\n> +++ b/include/libcamera/meson.build\n> @@ -12,6 +12,7 @@ libcamera_api = files([\n>      'signal.h',\n>      'stream.h',\n>      'timer.h',\n> +    'version.h',\n>  ])\n>  \n>  gen_header = join_paths(meson.current_source_dir(), 'gen-header.sh')\n> diff --git a/include/libcamera/version.h b/include/libcamera/version.h\n> new file mode 100644\n> index 000000000000..ad21f148e748\n> --- /dev/null\n> +++ b/include/libcamera/version.h\n> @@ -0,0 +1,23 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2019, Google Inc.\n> + *\n> + * version.h - Library version information\n> + */\n> +#ifndef __LIBCAMERA_VERSION_H__\n> +#define __LIBCAMERA_VERSION_H__\n> +\n> +namespace libcamera {\n> +\n> +class LibcameraVersion\n> +{\n> +public:\n> +\tLibcameraVersion();\n> +\tstd::string toString();\n> +};\n> +\n> +extern LibcameraVersion version;\n> +\n> +} /* namespace libcamera */\n> +\n> +#endif /* __LIBCAMERA_VERSION_H__ */\n\nThis seems a bit overkill, can't we just install version.h ?\n\n> diff --git a/meson.build b/meson.build\n> index 4d3e99d3e58f..5182546382c5 100644\n> --- a/meson.build\n> +++ b/meson.build\n> @@ -1,6 +1,8 @@\n>  project('libcamera', 'c', 'cpp',\n>      meson_version : '>= 0.40',\n> -    version : '0.1',\n> +    version : run_command('utils/version-gen',\n> +                          '@0@'.format(meson.source_root()),\n> +                          check : true).stdout().strip(),\n>      default_options : [\n>          'werror=true',\n>          'warning_level=2',\n> @@ -13,6 +15,11 @@ project('libcamera', 'c', 'cpp',\n>  #       generated from this too.\n>  api_version = '0.1'\n>  \n> +vcs_tag(command: ['utils/version-gen', '.'],\n> +        input: 'version.h.in',\n> +\toutput: 'version.h',\n> +\tfallback: '')\n\nMixing tabs and spaces.\n\nDon't you need to add the customtarget object returned by vcs_tag to\ndependencies or sources for something ? Otherwise meson won't know what\ndepends on version.h.\n\n> +\n>  cc = meson.get_compiler('c')\n>  config_h = configuration_data()\n>  \n> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> index 1ca1083cf5c7..b9a4153839c9 100644\n> --- a/src/libcamera/meson.build\n> +++ b/src/libcamera/meson.build\n> @@ -25,6 +25,7 @@ libcamera_sources = files([\n>      'utils.cpp',\n>      'v4l2_device.cpp',\n>      'v4l2_subdevice.cpp',\n> +    'version.cpp',\n>  ])\n>  \n>  libcamera_headers = files([\n> diff --git a/src/libcamera/version.cpp b/src/libcamera/version.cpp\n> new file mode 100644\n> index 000000000000..81f692f7cae7\n> --- /dev/null\n> +++ b/src/libcamera/version.cpp\n> @@ -0,0 +1,40 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2019, Google Inc.\n> + *\n> + * version.cpp - Version information\n> + */\n> +\n> +#include <libcamera/version.h>\n> +\n> +#include \"log.h\"\n> +\n> +/* The version header is automatically generated at the base of the project. */\n> +#include \"../../version.h\"\n> +\n> +namespace libcamera {\n> +\n> +LOG_DEFINE_CATEGORY(Version)\n> +\n> +/**\n> + * \\class LibcameraVersion\n> + *\n> + * Reports library version information\n> + */\n> +\n> +LibcameraVersion::LibcameraVersion()\n> +{\n> +\tLOG(Version, Info) << \"Libcamera Version \" << toString();\n> +}\n> +\n> +/**\n> + * \\brief Return the library version as a string\n> + */\n> +std::string LibcameraVersion::toString()\n> +{\n> +\treturn LIBCAMERA_VERSION;\n> +}\n> +\n> +static LibcameraVersion version;\n> +\n> +} /* namespace libcamera */\n> diff --git a/utils/version-gen b/utils/version-gen\n> new file mode 100755\n> index 000000000000..b8e53d77b63e\n> --- /dev/null\n> +++ b/utils/version-gen\n> @@ -0,0 +1,36 @@\n> +#!/bin/sh\n\nMissing SPDX header.\n\n> +\n> +if test -n \"$1\"\n\nPlease use\n\nif [[ ]] ; then\n\nOur scripts rely on bash, so I think I would specify that explicitly\ninstead of /bin/sh.\n\n> +then\n> +\tcd \"$1\"\n> +fi\n> +\n> +# No fall back is provided for tarball releases or such, as we do not yet provide releases.\n\nLine break at 80 columns ?\n\nTarball releases should just ship version.h.\n\n> +\n> +# Get a short description from the tree.\n> +version=$(git describe --abbrev=4 --match \"v[0-9]*\" 2>/dev/null)\n> +\n> +if test -z \"$version\"\n> +then\n\nif [[ -z \"$version\" ]] ; then\n\n> +\t# Handle an un-tagged repository\n> +\tsha=$(git describe --abbrev=4 --always 2>/dev/null)\n> +\tcommits=$(git log --oneline | wc -l 2>/dev/null)\n> +\tversion=v0.0.$commits.$sha\n> +fi\n> +\n> +\n> +git update-index --refresh > /dev/null 2>&1\n\nWhat does this do ?\n\n> +dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=\n\n$(...) instead of `...`\n\n> +\n> +# Strip the 'g'\n\nAnything wrong with the 'g' ? :-)\n\n> +version=$(echo \"$version\" | sed -e 's/-g/-/g')\n> +\n> +# Fix the '-' (the patch count) to a '.' as a version increment.\n> +version=$(echo \"$version\" | sed -e 's/-/./g')\n> +\n> +if test -n \"$dirty\"\n> +then\n\nif [[ -n \"$dirty\" ]] ; then\n\n> +\tversion=$version-dirty\n> +fi\n> +\n> +echo $version\n> diff --git a/version.h.in b/version.h.in\n> new file mode 100644\n> index 000000000000..142819645b64\n> --- /dev/null\n> +++ b/version.h.in\n> @@ -0,0 +1,3 @@\n\nShould this have a comment stating that the file is auto-generated ?\n\n> +#pragma once\n\nWe usually use #ifdef #define #endif, is there a specific reason to use\na #pragma instead ?\n\n> +\n> +#define LIBCAMERA_VERSION \"@VCS_TAG@\"","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id AD65A61FB9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 11 Jun 2019 22:32:53 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1E619FA0;\n\tTue, 11 Jun 2019 22:32:53 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1560285173;\n\tbh=iR5p+ggwrn+10ZGtRIAX7rLmp6kGB+pZ9rVhkg4Xgw0=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=s1shT/9kARgxNLl1D3sI+pCx8O8snTF9LzMWj3CtYNk19Nge2vFW1mSx9DmdPzvFJ\n\tE8fh6z16ZE6STdjtqb0t6lX3aOC2vH3bhrgdeKSe3wpiMJI3yEE7YJy6Vo0brm719w\n\tYKuVkPFiNEopiTO/x5Ykp07o96o7i4MMkQtwmLa0=","Date":"Tue, 11 Jun 2019 23:32:37 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"LibCamera Devel <libcamera-devel@lists.libcamera.org>","Message-ID":"<20190611203237.GY5016@pendragon.ideasonboard.com>","References":"<20190611201411.16369-1-kieran.bingham@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20190611201411.16369-1-kieran.bingham@ideasonboard.com>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH] libcamera: Auto generate version\n\tinformation","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Tue, 11 Jun 2019 20:32:53 -0000"}},{"id":1864,"web_url":"https://patchwork.libcamera.org/comment/1864/","msgid":"<1bbfce75-cce7-e85e-e060-66263335294d@ideasonboard.com>","date":"2019-06-11T22:25:43","subject":"Re: [libcamera-devel] [PATCH] libcamera: Auto generate version\n\tinformation","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 11/06/2019 21:32, Laurent Pinchart wrote:\n> Hi Kieran,\n> \n> Thank you for the patch.\n> \n> On Tue, Jun 11, 2019 at 09:14:11PM +0100, Kieran Bingham wrote:\n>> Generate a version string, and provide a global singleton object which\n>> allows applications to interogate the current libcamera version\n>> information.\n>>\n>> The version header is automatically updated by meson on each build.\n>> The string roughly follows the semver [0] conventions of\n>> major.minor.patch-label as a value.\n>>\n>> [0] https://semver.org/\n>>\n>> The utils/version-gen script will look for tags in the form vX.Y as\n>> starting points for the version string. While the repository does not\n>> have any matching tags, v0.0 will be assumed, resulting in versions with\n>> both major and minor being set to '0', and the patch count resulting\n>> from the number of patches in the history to that point.\n>>\n>> Finally, a uniquely identifying shortened checksum is provided from git:\n>>\n>> \tv0.0.509.c544\n>>\n>> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>> ---\n>>  Documentation/conf.py         |  6 ++++--\n>>  include/libcamera/meson.build |  1 +\n>>  include/libcamera/version.h   | 23 ++++++++++++++++++++\n>>  meson.build                   |  9 +++++++-\n>>  src/libcamera/meson.build     |  1 +\n>>  src/libcamera/version.cpp     | 40 +++++++++++++++++++++++++++++++++++\n>>  utils/version-gen             | 36 +++++++++++++++++++++++++++++++\n>>  version.h.in                  |  3 +++\n>>  8 files changed, 116 insertions(+), 3 deletions(-)\n>>  create mode 100644 include/libcamera/version.h\n>>  create mode 100644 src/libcamera/version.cpp\n>>  create mode 100755 utils/version-gen\n>>  create mode 100644 version.h.in\n>>\n>> diff --git a/Documentation/conf.py b/Documentation/conf.py\n>> index 970edf3d7298..e5980b98216d 100644\n>> --- a/Documentation/conf.py\n>> +++ b/Documentation/conf.py\n>> @@ -23,10 +23,12 @@ project = 'libcamera'\n>>  copyright = '2018-2019, The libcamera documentation authors'\n>>  author = u'Kieran Bingham, Jacopo Mondi, Laurent Pinchart, Niklas Söderlund'\n>>  \n>> +# Vesion information is provided by the build environment.\n> \n> s/Vesion/Version/\n\nEeep. Fixed.\n\n> \n>> +#\n>>  # The short X.Y version\n>> -version = ''\n>> +# version = ''\n>>  # The full version, including alpha/beta/rc tags\n>> -release = '0.1'\n>> +# release = '0.1'\n> \n> Should we just delete the version and release lines ?\n\nI chose to keep these intentionally. The rest of the conf.py contains\n'template' lines.\n\nI can remove if you prefer, but the whole conf.py could probably be\nstripped right down too.\n\n> \n>>  # -- General configuration ---------------------------------------------------\n>> diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\n>> index 1b86fdc7fca4..201832105457 100644\n>> --- a/include/libcamera/meson.build\n>> +++ b/include/libcamera/meson.build\n>> @@ -12,6 +12,7 @@ libcamera_api = files([\n>>      'signal.h',\n>>      'stream.h',\n>>      'timer.h',\n>> +    'version.h',\n>>  ])\n>>  \n>>  gen_header = join_paths(meson.current_source_dir(), 'gen-header.sh')\n>> diff --git a/include/libcamera/version.h b/include/libcamera/version.h\n>> new file mode 100644\n>> index 000000000000..ad21f148e748\n>> --- /dev/null\n>> +++ b/include/libcamera/version.h\n>> @@ -0,0 +1,23 @@\n>> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n>> +/*\n>> + * Copyright (C) 2019, Google Inc.\n>> + *\n>> + * version.h - Library version information\n>> + */\n>> +#ifndef __LIBCAMERA_VERSION_H__\n>> +#define __LIBCAMERA_VERSION_H__\n>> +\n>> +namespace libcamera {\n>> +\n>> +class LibcameraVersion\n>> +{\n>> +public:\n>> +\tLibcameraVersion();\n>> +\tstd::string toString();\n>> +};\n>> +\n>> +extern LibcameraVersion version;\n>> +\n>> +} /* namespace libcamera */\n>> +\n>> +#endif /* __LIBCAMERA_VERSION_H__ */\n> \n> This seems a bit overkill, can't we just install version.h ?\n\nI wanted to provide a way for an application or otherwise to obtain the\ninformation at runtime.\n\nThe static global instance 'version' prints a debug line through our LOG\ninterface at library start up, and I wanted to be able to expose that\nstring if needed.\n\nHrm... seems I messed up the patch anyway, I can't extern a static :-) -\nMaking it just 'global' to fix.\n\n\n>> diff --git a/meson.build b/meson.build\n>> index 4d3e99d3e58f..5182546382c5 100644\n>> --- a/meson.build\n>> +++ b/meson.build\n>> @@ -1,6 +1,8 @@\n>>  project('libcamera', 'c', 'cpp',\n>>      meson_version : '>= 0.40',\n>> -    version : '0.1',\n>> +    version : run_command('utils/version-gen',\n>> +                          '@0@'.format(meson.source_root()),\n>> +                          check : true).stdout().strip(),\n>>      default_options : [\n>>          'werror=true',\n>>          'warning_level=2',\n>> @@ -13,6 +15,11 @@ project('libcamera', 'c', 'cpp',\n>>  #       generated from this too.\n>>  api_version = '0.1'\n>>  \n>> +vcs_tag(command: ['utils/version-gen', '.'],\n>> +        input: 'version.h.in',\n>> +\toutput: 'version.h',\n>> +\tfallback: '')\n> \n> Mixing tabs and spaces.\n\nOops! I thought I fixed that.\n\n\n> Don't you need to add the customtarget object returned by vcs_tag to\n> dependencies or sources for something ? Otherwise meson won't know what\n> depends on version.h.\n\nI think you're right, but I can't see how to express a dependency on\nonly a single object file.\n\nI'll have to ask that one in #mesonbuild.\n\nI don't know what magic is happening, but it does seem to be doing the\nright thing anyway.\n\nI've tested this with a few iterations of changing files that should not\ndirectly recreate the version.o or libcamera.so - but does affect the\nversion-gen output, such as changing between a clean tree, and a -dirty\nlabel - and the library does seem to be correctly updated.\n\nI'll call this one 'resolved by magic' for now.\n\n>> +\n>>  cc = meson.get_compiler('c')\n>>  config_h = configuration_data()\n>>  \n>> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n>> index 1ca1083cf5c7..b9a4153839c9 100644\n>> --- a/src/libcamera/meson.build\n>> +++ b/src/libcamera/meson.build\n>> @@ -25,6 +25,7 @@ libcamera_sources = files([\n>>      'utils.cpp',\n>>      'v4l2_device.cpp',\n>>      'v4l2_subdevice.cpp',\n>> +    'version.cpp',\n>>  ])\n>>  \n>>  libcamera_headers = files([\n>> diff --git a/src/libcamera/version.cpp b/src/libcamera/version.cpp\n>> new file mode 100644\n>> index 000000000000..81f692f7cae7\n>> --- /dev/null\n>> +++ b/src/libcamera/version.cpp\n>> @@ -0,0 +1,40 @@\n>> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n>> +/*\n>> + * Copyright (C) 2019, Google Inc.\n>> + *\n>> + * version.cpp - Version information\n>> + */\n>> +\n>> +#include <libcamera/version.h>\n>> +\n>> +#include \"log.h\"\n>> +\n>> +/* The version header is automatically generated at the base of the project. */\n>> +#include \"../../version.h\"\n>> +\n>> +namespace libcamera {\n>> +\n>> +LOG_DEFINE_CATEGORY(Version)\n>> +\n>> +/**\n>> + * \\class LibcameraVersion\n>> + *\n>> + * Reports library version information\n>> + */\n>> +\n>> +LibcameraVersion::LibcameraVersion()\n>> +{\n>> +\tLOG(Version, Info) << \"Libcamera Version \" << toString();\n>> +}\n>> +\n>> +/**\n>> + * \\brief Return the library version as a string\n>> + */\n>> +std::string LibcameraVersion::toString()\n>> +{\n>> +\treturn LIBCAMERA_VERSION;\n>> +}\n>> +\n>> +static LibcameraVersion version;\n>> +\n>> +} /* namespace libcamera */\n>> diff --git a/utils/version-gen b/utils/version-gen\n>> new file mode 100755\n>> index 000000000000..b8e53d77b63e\n>> --- /dev/null\n>> +++ b/utils/version-gen\n>> @@ -0,0 +1,36 @@\n>> +#!/bin/sh\n> \n> Missing SPDX header.\n\nAs a component of the build system, is this GPL? or LGPL?\n\n\n>> +\n>> +if test -n \"$1\"\n> \n> Please use\n> \n> if [[ ]] ; then\n> \n> Our scripts rely on bash, so I think I would specify that explicitly\n> instead of /bin/sh.\n\nI am intentionally trying to stay posix shell compliant.\n\nlibcamera$ git grep bash\nutils/ipu3/ipu3-capture.sh:#!/bin/bash\nutils/ipu3/ipu3-process.sh:#!/bin/bash\n\nThere's a big difference between non-essential helper scripts for a user\nto run - and a script which is executed by the build system...\n\nThus I'm not sure being reliant on bash is the right thing ...\n\nI should run shellcheck too :)\n\t(Fixed those warnings too)\n\n> \n>> +then\n>> +\tcd \"$1\"\n>> +fi\n>> +\n>> +# No fall back is provided for tarball releases or such, as we do not yet provide releases.\n> \n> Line break at 80 columns ?\n> \n\nFixed.\n\n> Tarball releases should just ship version.h.\n\nSure, but the build system will have to know not to regenerate it.\n\nWe'll sort that later.\n\n>> +\n>> +# Get a short description from the tree.\n>> +version=$(git describe --abbrev=4 --match \"v[0-9]*\" 2>/dev/null)\n>> +\n>> +if test -z \"$version\"\n>> +then\n> \n> if [[ -z \"$version\" ]] ; then\n> \n>> +\t# Handle an un-tagged repository\n>> +\tsha=$(git describe --abbrev=4 --always 2>/dev/null)\n>> +\tcommits=$(git log --oneline | wc -l 2>/dev/null)\n>> +\tversion=v0.0.$commits.$sha\n>> +fi\n>> +\n>> +\n>> +git update-index --refresh > /dev/null 2>&1\n> \n> What does this do ?\n\nPrevents changed timestamps causing a -dirty label. I've added a comment.\n\n> \n>> +dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=\n> \n> $(...) instead of `...`\n> \n>> +\n>> +# Strip the 'g'\n> \n> Anything wrong with the 'g' ? :-)\n\nWould you like to keep it?\n\n>> +version=$(echo \"$version\" | sed -e 's/-g/-/g')\n>> +\n>> +# Fix the '-' (the patch count) to a '.' as a version increment.\n>> +version=$(echo \"$version\" | sed -e 's/-/./g')\n>> +\n>> +if test -n \"$dirty\"\n>> +then\n> \n> if [[ -n \"$dirty\" ]] ; then\n> \n>> +\tversion=$version-dirty\n>> +fi\n>> +\n>> +echo $version\n>> diff --git a/version.h.in b/version.h.in\n>> new file mode 100644\n>> index 000000000000..142819645b64\n>> --- /dev/null\n>> +++ b/version.h.in\n>> @@ -0,0 +1,3 @@\n> \n> Should this have a comment stating that the file is auto-generated ?\n\nAdded.\n\n> \n>> +#pragma once\n> \n> We usually use #ifdef #define #endif, is there a specific reason to use\n> a #pragma instead ?\n> \n\nProbably just because of the sample vcs_tag generator file I looked\nat... It was in January so I don't recall anything specific.\n (I'm trying to clear my backlog of misc patches)\n\nI'll change to #ifdefs\n\n>> +\n>> +#define LIBCAMERA_VERSION \"@VCS_TAG@\"\n>","headers":{"Return-Path":"<kieran.bingham@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7FD78618FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 12 Jun 2019 00:25:47 +0200 (CEST)","from [192.168.0.20]\n\t(cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AEB6BFA0;\n\tWed, 12 Jun 2019 00:25:46 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1560291946;\n\tbh=0hdlrz5e3u3MBHfNnyPJuWPJGKHTMXO2flq/476S5dU=;\n\th=Reply-To:Subject:To:Cc:References:From:Date:In-Reply-To:From;\n\tb=Zhbnx7uNX7wrJ+HS40dTAIvKwBV8ETs6XESlwz9BsfcvQkIYXJxWg9hf9XcGzdTCO\n\tmKFoMyA91x7kDUk1iM5jTQKAm6jFFB66sI89p0O0JJKWrJnZX3t7+9TlsiMat/1TBH\n\tKAouG3E3IdHpejXlzOe08fSDzV+ZnkBdIcr27cgg=","Reply-To":"kieran.bingham@ideasonboard.com","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"LibCamera Devel <libcamera-devel@lists.libcamera.org>","References":"<20190611201411.16369-1-kieran.bingham@ideasonboard.com>\n\t<20190611203237.GY5016@pendragon.ideasonboard.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Openpgp":"preference=signencrypt","Autocrypt":"addr=kieran.bingham@ideasonboard.com; keydata=\n\t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\n\tsbsRB8KNNvVXBOVNwko86rQqF9drZuw=","Organization":"Ideas on Board","Message-ID":"<1bbfce75-cce7-e85e-e060-66263335294d@ideasonboard.com>","Date":"Tue, 11 Jun 2019 23:25:43 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101\n\tThunderbird/60.7.0","MIME-Version":"1.0","In-Reply-To":"<20190611203237.GY5016@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-GB","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH] libcamera: Auto generate version\n\tinformation","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Tue, 11 Jun 2019 22:25:47 -0000"}},{"id":1870,"web_url":"https://patchwork.libcamera.org/comment/1870/","msgid":"<20190612083950.GE5035@pendragon.ideasonboard.com>","date":"2019-06-12T08:39:50","subject":"Re: [libcamera-devel] [PATCH] libcamera: Auto generate version\n\tinformation","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Kieran,\n\nOn Tue, Jun 11, 2019 at 11:25:43PM +0100, Kieran Bingham wrote:\n> On 11/06/2019 21:32, Laurent Pinchart wrote:\n> > On Tue, Jun 11, 2019 at 09:14:11PM +0100, Kieran Bingham wrote:\n> >> Generate a version string, and provide a global singleton object which\n> >> allows applications to interogate the current libcamera version\n> >> information.\n> >>\n> >> The version header is automatically updated by meson on each build.\n> >> The string roughly follows the semver [0] conventions of\n> >> major.minor.patch-label as a value.\n> >>\n> >> [0] https://semver.org/\n> >>\n> >> The utils/version-gen script will look for tags in the form vX.Y as\n> >> starting points for the version string. While the repository does not\n> >> have any matching tags, v0.0 will be assumed, resulting in versions with\n> >> both major and minor being set to '0', and the patch count resulting\n> >> from the number of patches in the history to that point.\n> >>\n> >> Finally, a uniquely identifying shortened checksum is provided from git:\n> >>\n> >> \tv0.0.509.c544\n> >>\n> >> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> >> ---\n> >>  Documentation/conf.py         |  6 ++++--\n> >>  include/libcamera/meson.build |  1 +\n> >>  include/libcamera/version.h   | 23 ++++++++++++++++++++\n> >>  meson.build                   |  9 +++++++-\n> >>  src/libcamera/meson.build     |  1 +\n> >>  src/libcamera/version.cpp     | 40 +++++++++++++++++++++++++++++++++++\n> >>  utils/version-gen             | 36 +++++++++++++++++++++++++++++++\n> >>  version.h.in                  |  3 +++\n> >>  8 files changed, 116 insertions(+), 3 deletions(-)\n> >>  create mode 100644 include/libcamera/version.h\n> >>  create mode 100644 src/libcamera/version.cpp\n> >>  create mode 100755 utils/version-gen\n> >>  create mode 100644 version.h.in\n> >>\n> >> diff --git a/Documentation/conf.py b/Documentation/conf.py\n> >> index 970edf3d7298..e5980b98216d 100644\n> >> --- a/Documentation/conf.py\n> >> +++ b/Documentation/conf.py\n> >> @@ -23,10 +23,12 @@ project = 'libcamera'\n> >>  copyright = '2018-2019, The libcamera documentation authors'\n> >>  author = u'Kieran Bingham, Jacopo Mondi, Laurent Pinchart, Niklas Söderlund'\n> >>  \n> >> +# Vesion information is provided by the build environment.\n> > \n> > s/Vesion/Version/\n> \n> Eeep. Fixed.\n> \n> >> +#\n> >>  # The short X.Y version\n> >> -version = ''\n> >> +# version = ''\n> >>  # The full version, including alpha/beta/rc tags\n> >> -release = '0.1'\n> >> +# release = '0.1'\n> > \n> > Should we just delete the version and release lines ?\n> \n> I chose to keep these intentionally. The rest of the conf.py contains\n> 'template' lines.\n> \n> I can remove if you prefer, but the whole conf.py could probably be\n> stripped right down too.\n\nIf you want to keep them please make sure they match the stock template\nfile.\n\nBy the way, where does the build environment provide version information\nto sphinx ?\n\n> >>  # -- General configuration ---------------------------------------------------\n> >> diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\n> >> index 1b86fdc7fca4..201832105457 100644\n> >> --- a/include/libcamera/meson.build\n> >> +++ b/include/libcamera/meson.build\n> >> @@ -12,6 +12,7 @@ libcamera_api = files([\n> >>      'signal.h',\n> >>      'stream.h',\n> >>      'timer.h',\n> >> +    'version.h',\n> >>  ])\n> >>  \n> >>  gen_header = join_paths(meson.current_source_dir(), 'gen-header.sh')\n> >> diff --git a/include/libcamera/version.h b/include/libcamera/version.h\n> >> new file mode 100644\n> >> index 000000000000..ad21f148e748\n> >> --- /dev/null\n> >> +++ b/include/libcamera/version.h\n> >> @@ -0,0 +1,23 @@\n> >> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> >> +/*\n> >> + * Copyright (C) 2019, Google Inc.\n> >> + *\n> >> + * version.h - Library version information\n> >> + */\n> >> +#ifndef __LIBCAMERA_VERSION_H__\n> >> +#define __LIBCAMERA_VERSION_H__\n> >> +\n> >> +namespace libcamera {\n> >> +\n> >> +class LibcameraVersion\n> >> +{\n> >> +public:\n> >> +\tLibcameraVersion();\n> >> +\tstd::string toString();\n> >> +};\n> >> +\n> >> +extern LibcameraVersion version;\n> >> +\n> >> +} /* namespace libcamera */\n> >> +\n> >> +#endif /* __LIBCAMERA_VERSION_H__ */\n> > \n> > This seems a bit overkill, can't we just install version.h ?\n> \n> I wanted to provide a way for an application or otherwise to obtain the\n> information at runtime.\n\nSure, I think that's useful, but I think just moving version.h to\ninclude/libcamera/ and installing it would be better. Applications would\nhave access to the raw data, and can do whatever they want with it. I'd\ngo one step further, and provide numerical version information too, but\nthat can be for later.\n\n> The static global instance 'version' prints a debug line through our LOG\n> interface at library start up, and I wanted to be able to expose that\n> string if needed.\n\nIf you want to log the version I would do so in CameraManager. That's\nbetter than in a global constructor that would likely be called before\nthe logging infrastructure is initialised.\n\n> Hrm... seems I messed up the patch anyway, I can't extern a static :-) -\n> Making it just 'global' to fix.\n> \n> >> diff --git a/meson.build b/meson.build\n> >> index 4d3e99d3e58f..5182546382c5 100644\n> >> --- a/meson.build\n> >> +++ b/meson.build\n> >> @@ -1,6 +1,8 @@\n> >>  project('libcamera', 'c', 'cpp',\n> >>      meson_version : '>= 0.40',\n> >> -    version : '0.1',\n> >> +    version : run_command('utils/version-gen',\n> >> +                          '@0@'.format(meson.source_root()),\n> >> +                          check : true).stdout().strip(),\n> >>      default_options : [\n> >>          'werror=true',\n> >>          'warning_level=2',\n> >> @@ -13,6 +15,11 @@ project('libcamera', 'c', 'cpp',\n> >>  #       generated from this too.\n> >>  api_version = '0.1'\n> >>  \n> >> +vcs_tag(command: ['utils/version-gen', '.'],\n> >> +        input: 'version.h.in',\n> >> +\toutput: 'version.h',\n> >> +\tfallback: '')\n> > \n> > Mixing tabs and spaces.\n> \n> Oops! I thought I fixed that.\n> \n> > Don't you need to add the customtarget object returned by vcs_tag to\n> > dependencies or sources for something ? Otherwise meson won't know what\n> > depends on version.h.\n> \n> I think you're right, but I can't see how to express a dependency on\n> only a single object file.\n> \n> I'll have to ask that one in #mesonbuild.\n> \n> I don't know what magic is happening, but it does seem to be doing the\n> right thing anyway.\n\nUntil we hit the right race :-)\n\n> I've tested this with a few iterations of changing files that should not\n> directly recreate the version.o or libcamera.so - but does affect the\n> version-gen output, such as changing between a clean tree, and a -dirty\n> label - and the library does seem to be correctly updated.\n\nNote that once you have compiled the project, ninja will have generated\ndependency information, and will rebuild the .h and .cpp files\ncorrectly. To test for races you need to wipe the build directory. You\ncan then use 'ninja target' with the target being set to a file that\nincludes version.h, and watch it fail when building that target only.\n\n> I'll call this one 'resolved by magic' for now.\n> \n> >> +\n> >>  cc = meson.get_compiler('c')\n> >>  config_h = configuration_data()\n> >>  \n> >> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> >> index 1ca1083cf5c7..b9a4153839c9 100644\n> >> --- a/src/libcamera/meson.build\n> >> +++ b/src/libcamera/meson.build\n> >> @@ -25,6 +25,7 @@ libcamera_sources = files([\n> >>      'utils.cpp',\n> >>      'v4l2_device.cpp',\n> >>      'v4l2_subdevice.cpp',\n> >> +    'version.cpp',\n> >>  ])\n> >>  \n> >>  libcamera_headers = files([\n> >> diff --git a/src/libcamera/version.cpp b/src/libcamera/version.cpp\n> >> new file mode 100644\n> >> index 000000000000..81f692f7cae7\n> >> --- /dev/null\n> >> +++ b/src/libcamera/version.cpp\n> >> @@ -0,0 +1,40 @@\n> >> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> >> +/*\n> >> + * Copyright (C) 2019, Google Inc.\n> >> + *\n> >> + * version.cpp - Version information\n> >> + */\n> >> +\n> >> +#include <libcamera/version.h>\n> >> +\n> >> +#include \"log.h\"\n> >> +\n> >> +/* The version header is automatically generated at the base of the project. */\n> >> +#include \"../../version.h\"\n> >> +\n> >> +namespace libcamera {\n> >> +\n> >> +LOG_DEFINE_CATEGORY(Version)\n> >> +\n> >> +/**\n> >> + * \\class LibcameraVersion\n> >> + *\n> >> + * Reports library version information\n> >> + */\n> >> +\n> >> +LibcameraVersion::LibcameraVersion()\n> >> +{\n> >> +\tLOG(Version, Info) << \"Libcamera Version \" << toString();\n> >> +}\n> >> +\n> >> +/**\n> >> + * \\brief Return the library version as a string\n> >> + */\n> >> +std::string LibcameraVersion::toString()\n> >> +{\n> >> +\treturn LIBCAMERA_VERSION;\n> >> +}\n> >> +\n> >> +static LibcameraVersion version;\n> >> +\n> >> +} /* namespace libcamera */\n> >> diff --git a/utils/version-gen b/utils/version-gen\n> >> new file mode 100755\n> >> index 000000000000..b8e53d77b63e\n> >> --- /dev/null\n> >> +++ b/utils/version-gen\n> >> @@ -0,0 +1,36 @@\n> >> +#!/bin/sh\n> > \n> > Missing SPDX header.\n> \n> As a component of the build system, is this GPL? or LGPL?\n\nI'd say GPL-2+. I just realised that gen-headers doesn't have an SPDX\nheader either. Feel free to fix both, or I can send a patch.\n\n> >> +\n> >> +if test -n \"$1\"\n> > \n> > Please use\n> > \n> > if [[ ]] ; then\n> > \n> > Our scripts rely on bash, so I think I would specify that explicitly\n> > instead of /bin/sh.\n> \n> I am intentionally trying to stay posix shell compliant.\n> \n> libcamera$ git grep bash\n> utils/ipu3/ipu3-capture.sh:#!/bin/bash\n> utils/ipu3/ipu3-process.sh:#!/bin/bash\n> \n> There's a big difference between non-essential helper scripts for a user\n> to run - and a script which is executed by the build system...\n> \n> Thus I'm not sure being reliant on bash is the right thing ...\n\nI believe we'll introduce bash-isms even if we try not to, and they will\nresult in failures later. If we mandate usage of bash it should be less\nof an issue. If you're confident about being able to write 100%\nposix-compliant shell script, I would use [ instead of [[.\n\n> I should run shellcheck too :)\n> \t(Fixed those warnings too)\n> \n> >> +then\n> >> +\tcd \"$1\"\n> >> +fi\n> >> +\n> >> +# No fall back is provided for tarball releases or such, as we do not yet provide releases.\n> > \n> > Line break at 80 columns ?\n> \n> Fixed.\n> \n> > Tarball releases should just ship version.h.\n> \n> Sure, but the build system will have to know not to regenerate it.\n> \n> We'll sort that later.\n> \n> >> +\n> >> +# Get a short description from the tree.\n> >> +version=$(git describe --abbrev=4 --match \"v[0-9]*\" 2>/dev/null)\n> >> +\n> >> +if test -z \"$version\"\n> >> +then\n> > \n> > if [[ -z \"$version\" ]] ; then\n> > \n> >> +\t# Handle an un-tagged repository\n> >> +\tsha=$(git describe --abbrev=4 --always 2>/dev/null)\n> >> +\tcommits=$(git log --oneline | wc -l 2>/dev/null)\n> >> +\tversion=v0.0.$commits.$sha\n> >> +fi\n> >> +\n> >> +\n> >> +git update-index --refresh > /dev/null 2>&1\n> > \n> > What does this do ?\n> \n> Prevents changed timestamps causing a -dirty label. I've added a comment.\n> \n> >> +dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=\n> > \n> > $(...) instead of `...`\n> > \n> >> +\n> >> +# Strip the 'g'\n> > \n> > Anything wrong with the 'g' ? :-)\n> \n> Would you like to keep it?\n\nI don't mind either way, it's included in the Linux kernel version so I\ngot used to it, I think it would confuse me a bit not to have it.\n\n> >> +version=$(echo \"$version\" | sed -e 's/-g/-/g')\n> >> +\n> >> +# Fix the '-' (the patch count) to a '.' as a version increment.\n> >> +version=$(echo \"$version\" | sed -e 's/-/./g')\n> >> +\n> >> +if test -n \"$dirty\"\n> >> +then\n> > \n> > if [[ -n \"$dirty\" ]] ; then\n> > \n> >> +\tversion=$version-dirty\n> >> +fi\n> >> +\n> >> +echo $version\n> >> diff --git a/version.h.in b/version.h.in\n> >> new file mode 100644\n> >> index 000000000000..142819645b64\n> >> --- /dev/null\n> >> +++ b/version.h.in\n> >> @@ -0,0 +1,3 @@\n> > \n> > Should this have a comment stating that the file is auto-generated ?\n> \n> Added.\n> \n> >> +#pragma once\n> > \n> > We usually use #ifdef #define #endif, is there a specific reason to use\n> > a #pragma instead ?\n> \n> Probably just because of the sample vcs_tag generator file I looked\n> at... It was in January so I don't recall anything specific.\n>  (I'm trying to clear my backlog of misc patches)\n> \n> I'll change to #ifdefs\n> \n> >> +\n> >> +#define LIBCAMERA_VERSION \"@VCS_TAG@\"","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B888261E84\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 12 Jun 2019 10:40:05 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 224AB336;\n\tWed, 12 Jun 2019 10:40:05 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1560328805;\n\tbh=DtuT4nrZJFrMcCSqLVtxsfQuoteyEtHsXGqBojoEKSM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=MRDeus85p2RGOQk7hVvKpLdq5bPaIe9KRMlXT0HczpjwnrTfVrzAbscp385FHOZGm\n\t8+IGrt/oe6tZAflCRHa3SfJ5Lz70JyHKuPASAmXrR2eYmBxsWwGVA0ASxE9F002Y2t\n\toI6+mNyMGbRAEj7FOJdf/FwUMkDARkInm+FIVj+c=","Date":"Wed, 12 Jun 2019 11:39:50 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"LibCamera Devel <libcamera-devel@lists.libcamera.org>","Message-ID":"<20190612083950.GE5035@pendragon.ideasonboard.com>","References":"<20190611201411.16369-1-kieran.bingham@ideasonboard.com>\n\t<20190611203237.GY5016@pendragon.ideasonboard.com>\n\t<1bbfce75-cce7-e85e-e060-66263335294d@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<1bbfce75-cce7-e85e-e060-66263335294d@ideasonboard.com>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH] libcamera: Auto generate version\n\tinformation","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Wed, 12 Jun 2019 08:40:06 -0000"}},{"id":1871,"web_url":"https://patchwork.libcamera.org/comment/1871/","msgid":"<b2eee89e-f863-3b99-f7e6-c2eb98d476d2@ideasonboard.com>","date":"2019-06-12T09:30:45","subject":"Re: [libcamera-devel] [PATCH] libcamera: Auto generate version\n\tinformation","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 12/06/2019 09:39, Laurent Pinchart wrote:\n> Hi Kieran,\n> \n> On Tue, Jun 11, 2019 at 11:25:43PM +0100, Kieran Bingham wrote:\n>> On 11/06/2019 21:32, Laurent Pinchart wrote:\n>>> On Tue, Jun 11, 2019 at 09:14:11PM +0100, Kieran Bingham wrote:\n>>>> Generate a version string, and provide a global singleton object which\n>>>> allows applications to interogate the current libcamera version\n>>>> information.\n>>>>\n>>>> The version header is automatically updated by meson on each build.\n>>>> The string roughly follows the semver [0] conventions of\n>>>> major.minor.patch-label as a value.\n>>>>\n>>>> [0] https://semver.org/\n>>>>\n>>>> The utils/version-gen script will look for tags in the form vX.Y as\n>>>> starting points for the version string. While the repository does not\n>>>> have any matching tags, v0.0 will be assumed, resulting in versions with\n>>>> both major and minor being set to '0', and the patch count resulting\n>>>> from the number of patches in the history to that point.\n>>>>\n>>>> Finally, a uniquely identifying shortened checksum is provided from git:\n>>>>\n>>>> \tv0.0.509.c544\n>>>>\n>>>> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>>>> ---\n>>>>  Documentation/conf.py         |  6 ++++--\n>>>>  include/libcamera/meson.build |  1 +\n>>>>  include/libcamera/version.h   | 23 ++++++++++++++++++++\n>>>>  meson.build                   |  9 +++++++-\n>>>>  src/libcamera/meson.build     |  1 +\n>>>>  src/libcamera/version.cpp     | 40 +++++++++++++++++++++++++++++++++++\n>>>>  utils/version-gen             | 36 +++++++++++++++++++++++++++++++\n>>>>  version.h.in                  |  3 +++\n>>>>  8 files changed, 116 insertions(+), 3 deletions(-)\n>>>>  create mode 100644 include/libcamera/version.h\n>>>>  create mode 100644 src/libcamera/version.cpp\n>>>>  create mode 100755 utils/version-gen\n>>>>  create mode 100644 version.h.in\n>>>>\n>>>> diff --git a/Documentation/conf.py b/Documentation/conf.py\n>>>> index 970edf3d7298..e5980b98216d 100644\n>>>> --- a/Documentation/conf.py\n>>>> +++ b/Documentation/conf.py\n>>>> @@ -23,10 +23,12 @@ project = 'libcamera'\n>>>>  copyright = '2018-2019, The libcamera documentation authors'\n>>>>  author = u'Kieran Bingham, Jacopo Mondi, Laurent Pinchart, Niklas Söderlund'\n>>>>  \n>>>> +# Vesion information is provided by the build environment.\n>>>\n>>> s/Vesion/Version/\n>>\n>> Eeep. Fixed.\n>>\n>>>> +#\n>>>>  # The short X.Y version\n>>>> -version = ''\n>>>> +# version = ''\n>>>>  # The full version, including alpha/beta/rc tags\n>>>> -release = '0.1'\n>>>> +# release = '0.1'\n>>>\n>>> Should we just delete the version and release lines ?\n>>\n>> I chose to keep these intentionally. The rest of the conf.py contains\n>> 'template' lines.\n>>\n>> I can remove if you prefer, but the whole conf.py could probably be\n>> stripped right down too.\n> \n> If you want to keep them please make sure they match the stock template\n> file.\n> \n> By the way, where does the build environment provide version information\n> to sphinx ?\n\nI have no idea. It 'just works' with this update, when you rebuild the\ndocumentation - the generated string is present in the output documentation.\n\nI did nothing specific to make this happen. It just happens when you\ndon't override the version and release tags in this file.\n\n\n>>>>  # -- General configuration ---------------------------------------------------\n>>>> diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\n>>>> index 1b86fdc7fca4..201832105457 100644\n>>>> --- a/include/libcamera/meson.build\n>>>> +++ b/include/libcamera/meson.build\n>>>> @@ -12,6 +12,7 @@ libcamera_api = files([\n>>>>      'signal.h',\n>>>>      'stream.h',\n>>>>      'timer.h',\n>>>> +    'version.h',\n>>>>  ])\n>>>>  \n>>>>  gen_header = join_paths(meson.current_source_dir(), 'gen-header.sh')\n>>>> diff --git a/include/libcamera/version.h b/include/libcamera/version.h\n>>>> new file mode 100644\n>>>> index 000000000000..ad21f148e748\n>>>> --- /dev/null\n>>>> +++ b/include/libcamera/version.h\n>>>> @@ -0,0 +1,23 @@\n>>>> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n>>>> +/*\n>>>> + * Copyright (C) 2019, Google Inc.\n>>>> + *\n>>>> + * version.h - Library version information\n>>>> + */\n>>>> +#ifndef __LIBCAMERA_VERSION_H__\n>>>> +#define __LIBCAMERA_VERSION_H__\n>>>> +\n>>>> +namespace libcamera {\n>>>> +\n>>>> +class LibcameraVersion\n>>>> +{\n>>>> +public:\n>>>> +\tLibcameraVersion();\n>>>> +\tstd::string toString();\n>>>> +};\n>>>> +\n>>>> +extern LibcameraVersion version;\n>>>> +\n>>>> +} /* namespace libcamera */\n>>>> +\n>>>> +#endif /* __LIBCAMERA_VERSION_H__ */\n>>>\n>>> This seems a bit overkill, can't we just install version.h ?\n>>\n>> I wanted to provide a way for an application or otherwise to obtain the\n>> information at runtime.\n> \n> Sure, I think that's useful, but I think just moving version.h to\n> include/libcamera/ and installing it would be better. Applications would\n> have access to the raw data, and can do whatever they want with it. I'd\n> go one step further, and provide numerical version information too, but\n> that can be for later.\n\nNo - then they have access to the information they *compile against*\nwhich (although it should be the same) might not be the same as the\nversion that they *run* against.\n\nI agree, it might be worth providing this at compile time too though.\n\n>> The static global instance 'version' prints a debug line through our LOG\n>> interface at library start up, and I wanted to be able to expose that\n>> string if needed.\n> \n> If you want to log the version I would do so in CameraManager. That's\n> better than in a global constructor that would likely be called before\n> the logging infrastructure is initialised.\n\nOK - that sounds reasonable too.\n\n\n>> Hrm... seems I messed up the patch anyway, I can't extern a static :-) -\n>> Making it just 'global' to fix.\n>>\n>>>> diff --git a/meson.build b/meson.build\n>>>> index 4d3e99d3e58f..5182546382c5 100644\n>>>> --- a/meson.build\n>>>> +++ b/meson.build\n>>>> @@ -1,6 +1,8 @@\n>>>>  project('libcamera', 'c', 'cpp',\n>>>>      meson_version : '>= 0.40',\n>>>> -    version : '0.1',\n>>>> +    version : run_command('utils/version-gen',\n>>>> +                          '@0@'.format(meson.source_root()),\n>>>> +                          check : true).stdout().strip(),\n>>>>      default_options : [\n>>>>          'werror=true',\n>>>>          'warning_level=2',\n>>>> @@ -13,6 +15,11 @@ project('libcamera', 'c', 'cpp',\n>>>>  #       generated from this too.\n>>>>  api_version = '0.1'\n>>>>  \n>>>> +vcs_tag(command: ['utils/version-gen', '.'],\n>>>> +        input: 'version.h.in',\n>>>> +\toutput: 'version.h',\n>>>> +\tfallback: '')\n>>>\n>>> Mixing tabs and spaces.\n>>\n>> Oops! I thought I fixed that.\n>>\n>>> Don't you need to add the customtarget object returned by vcs_tag to\n>>> dependencies or sources for something ? Otherwise meson won't know what\n>>> depends on version.h.\n>>\n>> I think you're right, but I can't see how to express a dependency on\n>> only a single object file.\n>>\n>> I'll have to ask that one in #mesonbuild.\n>>\n>> I don't know what magic is happening, but it does seem to be doing the\n>> right thing anyway.\n> \n> Until we hit the right race :-)\n\nSure I love a day at the races ! :)\n\n>> I've tested this with a few iterations of changing files that should not\n>> directly recreate the version.o or libcamera.so - but does affect the\n>> version-gen output, such as changing between a clean tree, and a -dirty\n>> label - and the library does seem to be correctly updated.\n> \n> Note that once you have compiled the project, ninja will have generated\n> dependency information, and will rebuild the .h and .cpp files\n> correctly. To test for races you need to wipe the build directory. You\n> can then use 'ninja target' with the target being set to a file that\n> includes version.h, and watch it fail when building that target only.\n\nOK - I haven't yet understood where that happens. My head is still stuck\nin the dark ages with autoconf, and I know how make used to create .d\nfiles - but ninja is still magic to me.\n\n\n>> I'll call this one 'resolved by magic' for now.\n>>\n\n\"Abracadabra, a dove\" ...\n<pulls white rabbit out of hat instead and looks perplexed>\n\n>>>> +\n>>>>  cc = meson.get_compiler('c')\n>>>>  config_h = configuration_data()\n>>>>  \n>>>> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n>>>> index 1ca1083cf5c7..b9a4153839c9 100644\n>>>> --- a/src/libcamera/meson.build\n>>>> +++ b/src/libcamera/meson.build\n>>>> @@ -25,6 +25,7 @@ libcamera_sources = files([\n>>>>      'utils.cpp',\n>>>>      'v4l2_device.cpp',\n>>>>      'v4l2_subdevice.cpp',\n>>>> +    'version.cpp',\n>>>>  ])\n>>>>  \n>>>>  libcamera_headers = files([\n>>>> diff --git a/src/libcamera/version.cpp b/src/libcamera/version.cpp\n>>>> new file mode 100644\n>>>> index 000000000000..81f692f7cae7\n>>>> --- /dev/null\n>>>> +++ b/src/libcamera/version.cpp\n>>>> @@ -0,0 +1,40 @@\n>>>> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n>>>> +/*\n>>>> + * Copyright (C) 2019, Google Inc.\n>>>> + *\n>>>> + * version.cpp - Version information\n>>>> + */\n>>>> +\n>>>> +#include <libcamera/version.h>\n>>>> +\n>>>> +#include \"log.h\"\n>>>> +\n>>>> +/* The version header is automatically generated at the base of the project. */\n>>>> +#include \"../../version.h\"\n>>>> +\n>>>> +namespace libcamera {\n>>>> +\n>>>> +LOG_DEFINE_CATEGORY(Version)\n>>>> +\n>>>> +/**\n>>>> + * \\class LibcameraVersion\n>>>> + *\n>>>> + * Reports library version information\n>>>> + */\n>>>> +\n>>>> +LibcameraVersion::LibcameraVersion()\n>>>> +{\n>>>> +\tLOG(Version, Info) << \"Libcamera Version \" << toString();\n>>>> +}\n>>>> +\n>>>> +/**\n>>>> + * \\brief Return the library version as a string\n>>>> + */\n>>>> +std::string LibcameraVersion::toString()\n>>>> +{\n>>>> +\treturn LIBCAMERA_VERSION;\n>>>> +}\n>>>> +\n>>>> +static LibcameraVersion version;\n>>>> +\n>>>> +} /* namespace libcamera */\n>>>> diff --git a/utils/version-gen b/utils/version-gen\n>>>> new file mode 100755\n>>>> index 000000000000..b8e53d77b63e\n>>>> --- /dev/null\n>>>> +++ b/utils/version-gen\n>>>> @@ -0,0 +1,36 @@\n>>>> +#!/bin/sh\n>>>\n>>> Missing SPDX header.\n>>\n>> As a component of the build system, is this GPL? or LGPL?\n> \n> I'd say GPL-2+. I just realised that gen-headers doesn't have an SPDX\n> header either. Feel free to fix both, or I can send a patch.\n\nLets fix gen-headers separately.\n\n>>>> +\n>>>> +if test -n \"$1\"\n>>>\n>>> Please use\n>>>\n>>> if [[ ]] ; then\n>>>\n>>> Our scripts rely on bash, so I think I would specify that explicitly\n>>> instead of /bin/sh.\n>>\n>> I am intentionally trying to stay posix shell compliant.\n>>\n>> libcamera$ git grep bash\n>> utils/ipu3/ipu3-capture.sh:#!/bin/bash\n>> utils/ipu3/ipu3-process.sh:#!/bin/bash\n>>\n>> There's a big difference between non-essential helper scripts for a user\n>> to run - and a script which is executed by the build system...\n>>\n>> Thus I'm not sure being reliant on bash is the right thing ...\n> \n> I believe we'll introduce bash-isms even if we try not to, and they will\n> result in failures later. If we mandate usage of bash it should be less\n> of an issue. If you're confident about being able to write 100%\n> posix-compliant shell script, I would use [ instead of [[.\n\nShellcheck will check for posix compliance when scripts begin with\n#!/bin/sh.\n\nThis might be another reason to just go back to importing the autoconf's\nimplementation:\n\nhttp://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=build-aux/git-version-gen\n\n>> I should run shellcheck too :)\n>> \t(Fixed those warnings too)\n>>\n>>>> +then\n>>>> +\tcd \"$1\"\n>>>> +fi\n>>>> +\n>>>> +# No fall back is provided for tarball releases or such, as we do not yet provide releases.\n>>>\n>>> Line break at 80 columns ?\n>>\n>> Fixed.\n>>\n>>> Tarball releases should just ship version.h.\n>>\n>> Sure, but the build system will have to know not to regenerate it.\n>>\n>> We'll sort that later.\n>>\n>>>> +\n>>>> +# Get a short description from the tree.\n>>>> +version=$(git describe --abbrev=4 --match \"v[0-9]*\" 2>/dev/null)\n>>>> +\n>>>> +if test -z \"$version\"\n>>>> +then\n>>>\n>>> if [[ -z \"$version\" ]] ; then\n>>>\n>>>> +\t# Handle an un-tagged repository\n>>>> +\tsha=$(git describe --abbrev=4 --always 2>/dev/null)\n>>>> +\tcommits=$(git log --oneline | wc -l 2>/dev/null)\n>>>> +\tversion=v0.0.$commits.$sha\n>>>> +fi\n>>>> +\n>>>> +\n>>>> +git update-index --refresh > /dev/null 2>&1\n>>>\n>>> What does this do ?\n>>\n>> Prevents changed timestamps causing a -dirty label. I've added a comment.\n>>\n>>>> +dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=\n>>>\n>>> $(...) instead of `...`\n>>>\n>>>> +\n>>>> +# Strip the 'g'\n>>>\n>>> Anything wrong with the 'g' ? :-)\n>>\n>> Would you like to keep it?\n> \n> I don't mind either way, it's included in the Linux kernel version so I\n> got used to it, I think it would confuse me a bit not to have it.\n\nThe 'methodology' I was following here was from the gnu git-version-gen\nwhich removes the 'g', as does the original \"GIT-VERSION-GEN\" from git\nitself.\n\nI had wanted to simplify things, hence splitting out our needs - but now\nI'm thinking it's better just to use the external script.\n\nI'll look again and decide before reposting, but I'll re-back-burner\nthis task for this week. It's consumed too many cycles already.\n\n>>>> +version=$(echo \"$version\" | sed -e 's/-g/-/g')\n>>>> +\n>>>> +# Fix the '-' (the patch count) to a '.' as a version increment.\n>>>> +version=$(echo \"$version\" | sed -e 's/-/./g')\n>>>> +\n>>>> +if test -n \"$dirty\"\n>>>> +then\n>>>\n>>> if [[ -n \"$dirty\" ]] ; then\n>>>\n>>>> +\tversion=$version-dirty\n>>>> +fi\n>>>> +\n>>>> +echo $version\n>>>> diff --git a/version.h.in b/version.h.in\n>>>> new file mode 100644\n>>>> index 000000000000..142819645b64\n>>>> --- /dev/null\n>>>> +++ b/version.h.in\n>>>> @@ -0,0 +1,3 @@\n>>>\n>>> Should this have a comment stating that the file is auto-generated ?\n>>\n>> Added.\n>>\n>>>> +#pragma once\n>>>\n>>> We usually use #ifdef #define #endif, is there a specific reason to use\n>>> a #pragma instead ?\n>>\n>> Probably just because of the sample vcs_tag generator file I looked\n>> at... It was in January so I don't recall anything specific.\n>>  (I'm trying to clear my backlog of misc patches)\n>>\n>> I'll change to #ifdefs\n>>\n>>>> +\n>>>> +#define LIBCAMERA_VERSION \"@VCS_TAG@\"\n>","headers":{"Return-Path":"<kieran.bingham@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 09CC461E4D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 12 Jun 2019 11:30:49 +0200 (CEST)","from [192.168.0.20]\n\t(cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4568B9B1;\n\tWed, 12 Jun 2019 11:30:48 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1560331848;\n\tbh=5Lu8I77/2qHdB5SxiT4bxLg5LH+om6fzOvpklWQ/hSg=;\n\th=Reply-To:Subject:To:Cc:References:From:Date:In-Reply-To:From;\n\tb=TIR3yvSW9QLFCLtEnfm9SToqsokj2foXBs9vUmQvIFhuYF5Vt4ZnMs417O6adAnJY\n\t+UkwVPZ87EcA312rU2+0nA9s/jVEnMjqr3JeU9NB4pNLZSjgliwd3wFtT4ndUInFo7\n\tz4UhwZgzWzuU/eP3fEW/p09W84qx9GFHvY+g2Rps=","Reply-To":"kieran.bingham@ideasonboard.com","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"LibCamera Devel <libcamera-devel@lists.libcamera.org>","References":"<20190611201411.16369-1-kieran.bingham@ideasonboard.com>\n\t<20190611203237.GY5016@pendragon.ideasonboard.com>\n\t<1bbfce75-cce7-e85e-e060-66263335294d@ideasonboard.com>\n\t<20190612083950.GE5035@pendragon.ideasonboard.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Openpgp":"preference=signencrypt","Autocrypt":"addr=kieran.bingham@ideasonboard.com; keydata=\n\t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\n\tsbsRB8KNNvVXBOVNwko86rQqF9drZuw=","Organization":"Ideas on Board","Message-ID":"<b2eee89e-f863-3b99-f7e6-c2eb98d476d2@ideasonboard.com>","Date":"Wed, 12 Jun 2019 10:30:45 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101\n\tThunderbird/60.7.0","MIME-Version":"1.0","In-Reply-To":"<20190612083950.GE5035@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-GB","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH] libcamera: Auto generate version\n\tinformation","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Wed, 12 Jun 2019 09:30:49 -0000"}}]