From f0657d4c8bd06ff6e8c8d0ba0a39162fcef37f3e Mon Sep 17 00:00:00 2001 From: Jens Maus Date: Mon, 2 Nov 2026 05:51:17 +0000 Subject: [PATCH 1/4] add a version to every program and library The programs hss_led, ssdpd, eq3configd, eq3configcmd, crypttool, SetInterfaceClock and hs485dLoader and the libraries libhsscomm, libelvutils, libLanDeviceUtils, libUnifiedLanComm and libeq3config get a version.sh like rfd, hs485d and multimacd: 2.3.0 for hss_led, which had "2.3" hard-coded, and 1.0.0 for the others. The new CMake function openccu_version_header() generates the header from it. The programs print the version with their usage or version option (ssdpd gets -v/--version); each library exports _VERSION_STRING. The SONAMEs stay unchanged. AGENTS.md now says where every component keeps its version and that a user-visible change raises it. --- AGENTS.md | 19 ++++++++++++++--- CMakeLists.txt | 23 +++++++++++++++++++++ src/SetInterfaceClock/CMakeLists.txt | 1 + src/SetInterfaceClock/SetInterfaceClock.cpp | 2 ++ src/SetInterfaceClock/version.sh | 9 ++++++++ src/crypttool/CMakeLists.txt | 1 + src/crypttool/crypttool.cpp | 2 ++ src/crypttool/version.sh | 9 ++++++++ src/eq3configcmd/CMakeLists.txt | 1 + src/eq3configcmd/eq3configcmd.cpp | 3 ++- src/eq3configcmd/version.sh | 9 ++++++++ src/eq3configd/CMakeLists.txt | 1 + src/eq3configd/main.cpp | 2 ++ src/eq3configd/version.sh | 9 ++++++++ src/hs485dLoader/CMakeLists.txt | 1 + src/hs485dLoader/hs485dLoader.cpp | 2 ++ src/hs485dLoader/version.sh | 9 ++++++++ src/hss_led/CMakeLists.txt | 3 +++ src/hss_led/LedCli.h | 3 ++- src/hss_led/version.sh | 9 ++++++++ src/libLanDeviceUtils/CMakeLists.txt | 3 +++ src/libLanDeviceUtils/src/version.cpp | 6 ++++++ src/libLanDeviceUtils/version.sh | 9 ++++++++ src/libUnifiedLanComm/CMakeLists.txt | 3 +++ src/libUnifiedLanComm/src/version.cpp | 6 ++++++ src/libUnifiedLanComm/version.sh | 9 ++++++++ src/libelvutils/CMakeLists.txt | 3 +++ src/libelvutils/version.cpp | 6 ++++++ src/libelvutils/version.sh | 9 ++++++++ src/libeq3config/CMakeLists.txt | 3 +++ src/libeq3config/version.cpp | 6 ++++++ src/libeq3config/version.sh | 9 ++++++++ src/libhsscomm/CMakeLists.txt | 3 +++ src/libhsscomm/version.cpp | 6 ++++++ src/libhsscomm/version.sh | 9 ++++++++ src/ssdpd/CMakeLists.txt | 1 + src/ssdpd/ssdpd.cpp | 6 ++++++ src/ssdpd/version.sh | 9 ++++++++ 38 files changed, 219 insertions(+), 5 deletions(-) create mode 100755 src/SetInterfaceClock/version.sh create mode 100755 src/crypttool/version.sh create mode 100755 src/eq3configcmd/version.sh create mode 100755 src/eq3configd/version.sh create mode 100755 src/hs485dLoader/version.sh create mode 100755 src/hss_led/version.sh create mode 100644 src/libLanDeviceUtils/src/version.cpp create mode 100755 src/libLanDeviceUtils/version.sh create mode 100644 src/libUnifiedLanComm/src/version.cpp create mode 100755 src/libUnifiedLanComm/version.sh create mode 100644 src/libelvutils/version.cpp create mode 100755 src/libelvutils/version.sh create mode 100644 src/libeq3config/version.cpp create mode 100755 src/libeq3config/version.sh create mode 100644 src/libhsscomm/version.cpp create mode 100755 src/libhsscomm/version.sh create mode 100755 src/ssdpd/version.sh diff --git a/AGENTS.md b/AGENTS.md index e620c7de0..2ba96280e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -47,9 +47,22 @@ what you could and could not test. `utf82ansi.py`). The prebuilt `libXmlRpc`/`libxmlparser` in `lib/` are regenerated by `.github/workflows/update-prebuilt-libraries.yml` after a merge. Never commit `build/`. -- **Daemon versions:** a user-visible change to `rfd` or `hs485d` bumps - `src//version.sh` and `src//generated--version.h` - together, either in the same pull request or in a collected bump. +- **Component versions:** every program and library under `src/` has a + version, kept in `version.sh` (the daemons, `hss_led`, `ssdpd`, `eq3configd`, + `eq3configcmd`, `crypttool`, `SetInterfaceClock`, `hs485dLoader`, + `libhsscomm`, `libelvutils`, `libLanDeviceUtils`, `libUnifiedLanComm`, + `libeq3config`), in `MODULE_VERSION` (`eq3_char_loop`, `bcm2835_raw_uart`), + in the Tcl package version (`tclrega`, `tclrpc`, `tcl_homematic`) or in the + library's own version (`XMLRPC_VERSION` of `libXmlRpc`, `@version` in + `xmlParser.h` of `libxmlparser`). + A user-visible change raises it (a fix the patch level, a new function the + minor version), either in the same pull request or in a collected bump. + CMake generates the header from `version.sh` with `openccu_version_header()`; + only `rfd` and `hs485d` keep a committed + `src//generated--version.h`, which is bumped together with + `version.sh`. Never give the shared libraries a CMake `VERSION` or + `SOVERSION`: their SONAME must stay the plain `lib.so`, which ReGaHss + and the OpenCCU packaging load. - **Daemon changelogs:** a pull request with a user-visible change to `rfd` or `hs485d` (including changes of the libraries they are built with) adds an entry to `src//CHANGELOG.md` under `## Unreleased` (create the diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d87e9312..19a34a174 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,29 @@ function(openccu_stage_target target_name dest_subdir) endfunction() +# Generates generated--version.h with "#define """ from +# the version.sh of the calling directory and lets include it. +function(openccu_version_header target name macro) + set(_text "${CMAKE_CURRENT_BINARY_DIR}/${name}-version.txt") + set(_header "${CMAKE_CURRENT_BINARY_DIR}/generated-${name}-version.h") + add_custom_command( + OUTPUT "${_header}" + BYPRODUCTS "${_text}" + COMMAND "${CMAKE_COMMAND}" -E env sh "${CMAKE_CURRENT_SOURCE_DIR}/version.sh" + > "${_text}" + COMMAND "${CMAKE_COMMAND}" + "-DINPUT=${_text}" + "-DOUTPUT=${_header}" + "-DMACRO_NAME=${macro}" -P "${CMAKE_SOURCE_DIR}/cmake/WriteVersionHeader.cmake" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/version.sh" + "${CMAKE_SOURCE_DIR}/cmake/WriteVersionHeader.cmake" + VERBATIM + ) + add_custom_target(${name}-version-header DEPENDS "${_header}") + add_dependencies(${target} ${name}-version-header) + target_include_directories(${target} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") +endfunction() + include(cmake/Components.cmake) message(STATUS "OpenCCU platform : ${TARGET_PLATFORM}") diff --git a/src/SetInterfaceClock/CMakeLists.txt b/src/SetInterfaceClock/CMakeLists.txt index 874afdf84..b04cca6f1 100644 --- a/src/SetInterfaceClock/CMakeLists.txt +++ b/src/SetInterfaceClock/CMakeLists.txt @@ -8,4 +8,5 @@ target_include_directories(SetInterfaceClock PRIVATE "${CMAKE_SOURCE_DIR}/src/libxmlparser" ) target_link_libraries(SetInterfaceClock PRIVATE XmlRpc hsscomm xmlparser elvutils pthread crypto) +openccu_version_header(SetInterfaceClock SetInterfaceClock SETINTERFACECLOCK_VERSION) openccu_stage_target(SetInterfaceClock bin) diff --git a/src/SetInterfaceClock/SetInterfaceClock.cpp b/src/SetInterfaceClock/SetInterfaceClock.cpp index ad36081f2..7d0d56996 100644 --- a/src/SetInterfaceClock/SetInterfaceClock.cpp +++ b/src/SetInterfaceClock/SetInterfaceClock.cpp @@ -15,6 +15,7 @@ #include #include #include +#include "generated-SetInterfaceClock-version.h" void printUsage(); @@ -102,6 +103,7 @@ std::string readPortFromFile(const char* filename) { void printUsage() { std::string msg; + msg.append("\nSetInterfaceClock " SETINTERFACECLOCK_VERSION " (" __DATE__ ")\n"); msg.append("\nSetInterfaceClock [IP:Port]\n"); msg.append("- Calls xml-rpc method SetInterfaceClock. -\n"); msg.append("Paremeters:\n"); diff --git a/src/SetInterfaceClock/version.sh b/src/SetInterfaceClock/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/SetInterfaceClock/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/crypttool/CMakeLists.txt b/src/crypttool/CMakeLists.txt index 0bf1e20aa..2565b756e 100644 --- a/src/crypttool/CMakeLists.txt +++ b/src/crypttool/CMakeLists.txt @@ -9,6 +9,7 @@ target_compile_options(crypttool PRIVATE -Wall) target_include_directories(crypttool PRIVATE "${CMAKE_SOURCE_DIR}/src/libelvutils") target_link_libraries(crypttool PRIVATE crypto pthread elvutils) +openccu_version_header(crypttool crypttool CRYPTTOOL_VERSION) openccu_stage_target(crypttool bin) add_custom_command(TARGET crypttool POST_BUILD diff --git a/src/crypttool/crypttool.cpp b/src/crypttool/crypttool.cpp index c31a11167..19342539e 100644 --- a/src/crypttool/crypttool.cpp +++ b/src/crypttool/crypttool.cpp @@ -22,11 +22,13 @@ #include "openssl/evp.h" #include "crypttoolconfig.h" +#include "generated-crypttool-version.h" const char* defaultKey = "Markus is awesome"; static void usage(const char* procname) { + printf("crypttool %s (%s)\n\n", CRYPTTOOL_VERSION, __DATE__); printf("%s [-k key] [-t key_type] [-e] [-d] [-s] [-S] [-v] [-r] [-g] [-y] [-l loglevel] [-f path/to/configFile]\n", procname); printf(" Actions: (Default action is to encrypt with the current user key)\n"); printf(" -d: decrypt\n"); diff --git a/src/crypttool/version.sh b/src/crypttool/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/crypttool/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/eq3configcmd/CMakeLists.txt b/src/eq3configcmd/CMakeLists.txt index dc11a0af8..f48ff8c7c 100644 --- a/src/eq3configcmd/CMakeLists.txt +++ b/src/eq3configcmd/CMakeLists.txt @@ -3,4 +3,5 @@ target_compile_features(eq3configcmd PRIVATE cxx_std_11) target_compile_definitions(eq3configcmd PRIVATE _TIME_BITS=64 _FILE_OFFSET_BITS=64) target_include_directories(eq3configcmd PRIVATE "${CMAKE_SOURCE_DIR}/src/libeq3config") target_link_libraries(eq3configcmd PRIVATE eq3config pthread crypto rt) +openccu_version_header(eq3configcmd eq3configcmd EQ3CONFIGCMD_VERSION) openccu_stage_target(eq3configcmd bin) diff --git a/src/eq3configcmd/eq3configcmd.cpp b/src/eq3configcmd/eq3configcmd.cpp index 81652543f..dc0db291f 100644 --- a/src/eq3configcmd/eq3configcmd.cpp +++ b/src/eq3configcmd/eq3configcmd.cpp @@ -12,6 +12,7 @@ #include #include +#include "generated-eq3configcmd-version.h" void printUsage(); void removeLeadingPathseperators(std::string& filename); @@ -64,7 +65,7 @@ int main(int argc, char** argv) void printUsage() { std::cout << std::endl - << "eq3configcmd, (c) 2013 eQ-3 Entwicklung GmbH" << std::endl + << "eq3configcmd " EQ3CONFIGCMD_VERSION " (" __DATE__ "), (c) 2013 eQ-3 Entwicklung GmbH" << std::endl << std::endl << "Usage:" << std::endl << "\t eq3configcmd []" << std::endl << std::endl diff --git a/src/eq3configcmd/version.sh b/src/eq3configcmd/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/eq3configcmd/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/eq3configd/CMakeLists.txt b/src/eq3configd/CMakeLists.txt index 528e2e3b1..4a6f62d42 100644 --- a/src/eq3configd/CMakeLists.txt +++ b/src/eq3configd/CMakeLists.txt @@ -13,4 +13,5 @@ target_include_directories(eq3configd PRIVATE ) target_link_libraries(eq3configd PRIVATE pthread crypto elvutils) +openccu_version_header(eq3configd eq3configd EQ3CONFIGD_VERSION) openccu_stage_target(eq3configd bin) diff --git a/src/eq3configd/main.cpp b/src/eq3configd/main.cpp index 4ba01d1e4..11501d355 100644 --- a/src/eq3configd/main.cpp +++ b/src/eq3configd/main.cpp @@ -28,6 +28,7 @@ #include #include "include/udpframe.h" +#include "generated-eq3configd-version.h" #include "include/networkconfig.h" #include @@ -59,6 +60,7 @@ const uint8_t UDP_CRYPT_SIGNATURE[UDP_CRYPT_SIGNATURE_SIZE] = "eQ-3__UDP-Crypt"; static void usage(const char* procname) { + printf("eq3configd %s (%s)\n\n", EQ3CONFIGD_VERSION, __DATE__); printf("%s [-c] [-l loglevel]\n", procname); printf(" Options:\n"); diff --git a/src/eq3configd/version.sh b/src/eq3configd/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/eq3configd/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/hs485dLoader/CMakeLists.txt b/src/hs485dLoader/CMakeLists.txt index 30a6ea522..3d4e9ed47 100644 --- a/src/hs485dLoader/CMakeLists.txt +++ b/src/hs485dLoader/CMakeLists.txt @@ -11,4 +11,5 @@ target_include_directories(hs485dLoader PRIVATE ) target_link_libraries(hs485dLoader PRIVATE pthread m c elvutils xmlparser) +openccu_version_header(hs485dLoader hs485dLoader HS485DLOADER_VERSION) openccu_stage_target(hs485dLoader bin) diff --git a/src/hs485dLoader/hs485dLoader.cpp b/src/hs485dLoader/hs485dLoader.cpp index 3e03d227d..c08da6264 100644 --- a/src/hs485dLoader/hs485dLoader.cpp +++ b/src/hs485dLoader/hs485dLoader.cpp @@ -18,6 +18,7 @@ #include #include #include +#include "generated-hs485dLoader-version.h" @@ -329,6 +330,7 @@ std::string trim(const std::string& str) void printUsage() { + printf("hs485dLoader %s (%s)\n\n", HS485DLOADER_VERSION, __DATE__); printf("hs485dLoader -l LEVEL [-ds] [-dw] [-dd] [-ilf /path/to/InterfacesList.xml] /pathto/hs485d.conf\n\n"); printf("\t-l LEVEL: Log Level for hs485d; Default is 5\n"); printf("\t-ds: Do not start hs485d, just write InterfacesList.xml\n"); diff --git a/src/hs485dLoader/version.sh b/src/hs485dLoader/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/hs485dLoader/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/hss_led/CMakeLists.txt b/src/hss_led/CMakeLists.txt index f71f75d5d..74110d776 100644 --- a/src/hss_led/CMakeLists.txt +++ b/src/hss_led/CMakeLists.txt @@ -32,6 +32,7 @@ target_include_directories(hss_led PRIVATE ) target_link_libraries(hss_led PRIVATE XmlRpc elvutils xmlparser pthread) endif() +openccu_version_header(hss_led hss_led HSS_LED_VERSION) set_property(TARGET hss_led PROPERTY OPENCCU_RUNTIME_ALIASES hss_ledctl) openccu_stage_target(hss_led bin) @@ -42,5 +43,7 @@ if(HSS_LED_BUILD_TESTS) target_compile_options(hss_led_state_test PRIVATE -Wall -Wextra -Werror) target_compile_definitions(hss_led_state_test PRIVATE LED_TEST_BUILD) target_link_libraries(hss_led_state_test PRIVATE pthread) + add_dependencies(hss_led_state_test hss_led-version-header) + target_include_directories(hss_led_state_test PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") add_test(NAME hss_led_state COMMAND hss_led_state_test) endif() diff --git a/src/hss_led/LedCli.h b/src/hss_led/LedCli.h index 013cc3e3f..3ecfa66e3 100644 --- a/src/hss_led/LedCli.h +++ b/src/hss_led/LedCli.h @@ -2,13 +2,14 @@ #ifndef OPENCCU_LED_CLI_H #define OPENCCU_LED_CLI_H #include +#include "generated-hss_led-version.h" namespace LedCli { static const unsigned slowMs = 500; static const unsigned fastMs = 100; inline void version(std::ostream& out, const char* program, bool recovery = false) { - out << program << " 2.3 (built " << __DATE__ << " " << __TIME__ << ")"; + out << program << " " HSS_LED_VERSION " (built " << __DATE__ << " " << __TIME__ << ")"; if (recovery) out << " [recovery]"; out << '\n'; } diff --git a/src/hss_led/version.sh b/src/hss_led/version.sh new file mode 100755 index 000000000..9aa010b7e --- /dev/null +++ b/src/hss_led/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="2" +MINOR="3" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/libLanDeviceUtils/CMakeLists.txt b/src/libLanDeviceUtils/CMakeLists.txt index 223569071..9605e7746 100644 --- a/src/libLanDeviceUtils/CMakeLists.txt +++ b/src/libLanDeviceUtils/CMakeLists.txt @@ -28,3 +28,6 @@ target_include_directories(LanDeviceUtils PRIVATE "${CMAKE_SOURCE_DIR}/src/libel target_link_libraries(LanDeviceUtils PRIVATE pthread crypto elvutils) set_target_properties(LanDeviceUtils PROPERTIES OUTPUT_NAME LanDeviceUtils) openccu_stage_target(LanDeviceUtils lib) + +target_sources(LanDeviceUtils PRIVATE src/version.cpp) +openccu_version_header(LanDeviceUtils LanDeviceUtils LANDEVICEUTILS_VERSION) diff --git a/src/libLanDeviceUtils/src/version.cpp b/src/libLanDeviceUtils/src/version.cpp new file mode 100644 index 000000000..8ac7bee52 --- /dev/null +++ b/src/libLanDeviceUtils/src/version.cpp @@ -0,0 +1,6 @@ +// Version of libLanDeviceUtils (see version.sh and CHANGELOG.md). A program can print it +// by declaring: extern const char LANDEVICEUTILS_VERSION_STRING[]; +#include "generated-LanDeviceUtils-version.h" + +extern const char LANDEVICEUTILS_VERSION_STRING[]; +const char LANDEVICEUTILS_VERSION_STRING[] = LANDEVICEUTILS_VERSION; diff --git a/src/libLanDeviceUtils/version.sh b/src/libLanDeviceUtils/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/libLanDeviceUtils/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/libUnifiedLanComm/CMakeLists.txt b/src/libUnifiedLanComm/CMakeLists.txt index f784ae84c..4a463a95d 100644 --- a/src/libUnifiedLanComm/CMakeLists.txt +++ b/src/libUnifiedLanComm/CMakeLists.txt @@ -20,3 +20,6 @@ target_include_directories(UnifiedLanComm PRIVATE target_link_libraries(UnifiedLanComm PRIVATE pthread LanDeviceUtils elvutils) set_target_properties(UnifiedLanComm PROPERTIES OUTPUT_NAME UnifiedLanComm) openccu_stage_target(UnifiedLanComm lib) + +target_sources(UnifiedLanComm PRIVATE src/version.cpp) +openccu_version_header(UnifiedLanComm UnifiedLanComm UNIFIEDLANCOMM_VERSION) diff --git a/src/libUnifiedLanComm/src/version.cpp b/src/libUnifiedLanComm/src/version.cpp new file mode 100644 index 000000000..b2ca7884f --- /dev/null +++ b/src/libUnifiedLanComm/src/version.cpp @@ -0,0 +1,6 @@ +// Version of libUnifiedLanComm (see version.sh and CHANGELOG.md). A program can print it +// by declaring: extern const char UNIFIEDLANCOMM_VERSION_STRING[]; +#include "generated-UnifiedLanComm-version.h" + +extern const char UNIFIEDLANCOMM_VERSION_STRING[]; +const char UNIFIEDLANCOMM_VERSION_STRING[] = UNIFIEDLANCOMM_VERSION; diff --git a/src/libUnifiedLanComm/version.sh b/src/libUnifiedLanComm/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/libUnifiedLanComm/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/libelvutils/CMakeLists.txt b/src/libelvutils/CMakeLists.txt index 8f9a90f92..4a30865a2 100644 --- a/src/libelvutils/CMakeLists.txt +++ b/src/libelvutils/CMakeLists.txt @@ -26,3 +26,6 @@ target_compile_options(elvutils PRIVATE -Wall -fPIC) target_link_libraries(elvutils PRIVATE crypto) set_target_properties(elvutils PROPERTIES OUTPUT_NAME elvutils) openccu_stage_target(elvutils lib) + +target_sources(elvutils PRIVATE version.cpp) +openccu_version_header(elvutils elvutils ELVUTILS_VERSION) diff --git a/src/libelvutils/version.cpp b/src/libelvutils/version.cpp new file mode 100644 index 000000000..7a812b91c --- /dev/null +++ b/src/libelvutils/version.cpp @@ -0,0 +1,6 @@ +// Version of libelvutils (see version.sh and CHANGELOG.md). A program can print it +// by declaring: extern const char ELVUTILS_VERSION_STRING[]; +#include "generated-elvutils-version.h" + +extern const char ELVUTILS_VERSION_STRING[]; +const char ELVUTILS_VERSION_STRING[] = ELVUTILS_VERSION; diff --git a/src/libelvutils/version.sh b/src/libelvutils/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/libelvutils/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/libeq3config/CMakeLists.txt b/src/libeq3config/CMakeLists.txt index 4d5e1c992..03e44d40d 100644 --- a/src/libeq3config/CMakeLists.txt +++ b/src/libeq3config/CMakeLists.txt @@ -52,3 +52,6 @@ target_include_directories(eq3config PRIVATE target_link_libraries(eq3config PRIVATE pthread rt crypto LanDeviceUtils UnifiedLanComm elvutils) set_target_properties(eq3config PROPERTIES OUTPUT_NAME eq3config) openccu_stage_target(eq3config lib) + +target_sources(eq3config PRIVATE version.cpp) +openccu_version_header(eq3config eq3config EQ3CONFIG_VERSION) diff --git a/src/libeq3config/version.cpp b/src/libeq3config/version.cpp new file mode 100644 index 000000000..a808ba86d --- /dev/null +++ b/src/libeq3config/version.cpp @@ -0,0 +1,6 @@ +// Version of libeq3config (see version.sh and CHANGELOG.md). A program can print it +// by declaring: extern const char EQ3CONFIG_VERSION_STRING[]; +#include "generated-eq3config-version.h" + +extern const char EQ3CONFIG_VERSION_STRING[]; +const char EQ3CONFIG_VERSION_STRING[] = EQ3CONFIG_VERSION; diff --git a/src/libeq3config/version.sh b/src/libeq3config/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/libeq3config/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/libhsscomm/CMakeLists.txt b/src/libhsscomm/CMakeLists.txt index 8a50cdd4c..958e87649 100644 --- a/src/libhsscomm/CMakeLists.txt +++ b/src/libhsscomm/CMakeLists.txt @@ -65,3 +65,6 @@ target_include_directories(hsscomm PRIVATE target_link_libraries(hsscomm PRIVATE pthread elvutils xmlparser XmlRpc) set_target_properties(hsscomm PROPERTIES OUTPUT_NAME hsscomm) openccu_stage_target(hsscomm lib) + +target_sources(hsscomm PRIVATE version.cpp) +openccu_version_header(hsscomm hsscomm HSSCOMM_VERSION) diff --git a/src/libhsscomm/version.cpp b/src/libhsscomm/version.cpp new file mode 100644 index 000000000..31debbfa5 --- /dev/null +++ b/src/libhsscomm/version.cpp @@ -0,0 +1,6 @@ +// Version of libhsscomm (see version.sh and CHANGELOG.md). A program can print it +// by declaring: extern const char HSSCOMM_VERSION_STRING[]; +#include "generated-hsscomm-version.h" + +extern const char HSSCOMM_VERSION_STRING[]; +const char HSSCOMM_VERSION_STRING[] = HSSCOMM_VERSION; diff --git a/src/libhsscomm/version.sh b/src/libhsscomm/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/libhsscomm/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION diff --git a/src/ssdpd/CMakeLists.txt b/src/ssdpd/CMakeLists.txt index 4316b743d..5419f2b09 100644 --- a/src/ssdpd/CMakeLists.txt +++ b/src/ssdpd/CMakeLists.txt @@ -7,4 +7,5 @@ target_compile_definitions(ssdpd PRIVATE _TIME_BITS=64 _FILE_OFFSET_BITS=64) target_compile_options(ssdpd PRIVATE -Wall) target_link_libraries(ssdpd PRIVATE pthread) +openccu_version_header(ssdpd ssdpd SSDPD_VERSION) openccu_stage_target(ssdpd bin) diff --git a/src/ssdpd/ssdpd.cpp b/src/ssdpd/ssdpd.cpp index e025af365..a0d73a870 100644 --- a/src/ssdpd/ssdpd.cpp +++ b/src/ssdpd/ssdpd.cpp @@ -18,6 +18,7 @@ #include #include #include +#include "generated-ssdpd-version.h" #include #include @@ -341,6 +342,11 @@ static std::string getSerialNum() { int main(int argc, char ** argv) { char buffer[2048]; + if(argc > 1 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { + printf("ssdpd %s (%s)\n", SSDPD_VERSION, __DATE__); + return 0; + } + struct sockaddr_in sa_mcast_client; struct sockaddr_in sa_peer; diff --git a/src/ssdpd/version.sh b/src/ssdpd/version.sh new file mode 100755 index 000000000..96ebb71e9 --- /dev/null +++ b/src/ssdpd/version.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +MAJOR="1" +MINOR="0" +PATCH="0" + +VERSION="$MAJOR.$MINOR.$PATCH" + +echo $VERSION From b78e0647d04129707c460505618a27220088f405 Mon Sep 17 00:00:00 2001 From: Jens Maus Date: Mon, 2 Nov 2026 10:41:51 +0000 Subject: [PATCH 2/4] add a version to every program and library: --version and version accessors eq3configd, crypttool, hs485dLoader, SetInterfaceClock and eq3configcmd now handle --version first in main(): it prints the version and exits, before eq3configd starts its service or SetInterfaceClock takes the argument as the address of its RPC call. The libraries export a function _version() instead of an array, so an executable cannot keep the array size of an older version through a copy relocation. --- src/SetInterfaceClock/SetInterfaceClock.cpp | 6 ++++++ src/crypttool/crypttool.cpp | 5 +++++ src/eq3configcmd/eq3configcmd.cpp | 6 ++++++ src/eq3configd/main.cpp | 5 +++++ src/hs485dLoader/hs485dLoader.cpp | 5 +++++ src/libLanDeviceUtils/src/version.cpp | 8 +++++--- src/libUnifiedLanComm/src/version.cpp | 8 +++++--- src/libelvutils/version.cpp | 8 +++++--- src/libeq3config/version.cpp | 8 +++++--- src/libhsscomm/version.cpp | 8 +++++--- 10 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/SetInterfaceClock/SetInterfaceClock.cpp b/src/SetInterfaceClock/SetInterfaceClock.cpp index 7d0d56996..b1251e57b 100644 --- a/src/SetInterfaceClock/SetInterfaceClock.cpp +++ b/src/SetInterfaceClock/SetInterfaceClock.cpp @@ -10,6 +10,7 @@ // #include #include +#include #include #include #include @@ -26,6 +27,11 @@ using namespace XmlRpc; int main(int argc, char* argv[]) { + if(argc == 2 && strcmp(argv[1], "--version") == 0) { + printf("SetInterfaceClock %s (%s)\n", SETINTERFACECLOCK_VERSION, __DATE__); + return 0; + } + Logger* log = (Logger*)new SyslogLogger("SetInterfaceClock"); log->SetLevel((Logger::LogLevel)1); diff --git a/src/crypttool/crypttool.cpp b/src/crypttool/crypttool.cpp index 19342539e..7fc9f0c5f 100644 --- a/src/crypttool/crypttool.cpp +++ b/src/crypttool/crypttool.cpp @@ -267,6 +267,11 @@ int get_index(crypttoolconfig& crypttoolconfig, int key_type) int main(int argc, char* argv[]) { + if(argc == 2 && strcmp(argv[1], "--version") == 0) { + printf("crypttool %s (%s)\n", CRYPTTOOL_VERSION, __DATE__); + return 0; + } + int key_type = -1; int key_index = -1; char* key = NULL; diff --git a/src/eq3configcmd/eq3configcmd.cpp b/src/eq3configcmd/eq3configcmd.cpp index dc0db291f..c50960fdd 100644 --- a/src/eq3configcmd/eq3configcmd.cpp +++ b/src/eq3configcmd/eq3configcmd.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "generated-eq3configcmd-version.h" @@ -19,6 +20,11 @@ void removeLeadingPathseperators(std::string& filename); int main(int argc, char** argv) { + if(argc == 2 && strcmp(argv[1], "--version") == 0) { + std::cout << "eq3configcmd " EQ3CONFIGCMD_VERSION " (" __DATE__ ")" << std::endl; + return 0; + } + if(argc >= 1) { //Parse command line args... //First must be the commandName diff --git a/src/eq3configd/main.cpp b/src/eq3configd/main.cpp index 11501d355..13cb0faf3 100644 --- a/src/eq3configd/main.cpp +++ b/src/eq3configd/main.cpp @@ -86,6 +86,11 @@ int main(int argc, char* argv[]) Logger::LogLevel loglevel=Logger::LOG_INFO; std::string deviceType = ""; + if(argc == 2 && strcmp(argv[1], "--version") == 0) { + printf("eq3configd %s (%s)\n", EQ3CONFIGD_VERSION, __DATE__); + return 0; + } + // analyse commandline parameters for(int i = 1; i < argc; i++) { diff --git a/src/hs485dLoader/hs485dLoader.cpp b/src/hs485dLoader/hs485dLoader.cpp index c08da6264..b13220c1b 100644 --- a/src/hs485dLoader/hs485dLoader.cpp +++ b/src/hs485dLoader/hs485dLoader.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,10 @@ int main(int argc, char** argv) bool writeInterfacesXML = true; bool startAsDaemon = true; std::string interfacesXmlPath("/etc/config/InterfacesList.xml"); + if(argc == 2 && strcmp(argv[1], "--version") == 0) { + printf("hs485dLoader %s (%s)\n", HS485DLOADER_VERSION, __DATE__); + return 0; + } //Parse args if(argc < 2) { printUsage(); diff --git a/src/libLanDeviceUtils/src/version.cpp b/src/libLanDeviceUtils/src/version.cpp index 8ac7bee52..b2cfec819 100644 --- a/src/libLanDeviceUtils/src/version.cpp +++ b/src/libLanDeviceUtils/src/version.cpp @@ -1,6 +1,8 @@ // Version of libLanDeviceUtils (see version.sh and CHANGELOG.md). A program can print it -// by declaring: extern const char LANDEVICEUTILS_VERSION_STRING[]; +// by declaring: extern "C" const char* landeviceutils_version(); #include "generated-LanDeviceUtils-version.h" -extern const char LANDEVICEUTILS_VERSION_STRING[]; -const char LANDEVICEUTILS_VERSION_STRING[] = LANDEVICEUTILS_VERSION; +extern "C" const char* landeviceutils_version() +{ + return LANDEVICEUTILS_VERSION; +} diff --git a/src/libUnifiedLanComm/src/version.cpp b/src/libUnifiedLanComm/src/version.cpp index b2ca7884f..75a169f88 100644 --- a/src/libUnifiedLanComm/src/version.cpp +++ b/src/libUnifiedLanComm/src/version.cpp @@ -1,6 +1,8 @@ // Version of libUnifiedLanComm (see version.sh and CHANGELOG.md). A program can print it -// by declaring: extern const char UNIFIEDLANCOMM_VERSION_STRING[]; +// by declaring: extern "C" const char* unifiedlancomm_version(); #include "generated-UnifiedLanComm-version.h" -extern const char UNIFIEDLANCOMM_VERSION_STRING[]; -const char UNIFIEDLANCOMM_VERSION_STRING[] = UNIFIEDLANCOMM_VERSION; +extern "C" const char* unifiedlancomm_version() +{ + return UNIFIEDLANCOMM_VERSION; +} diff --git a/src/libelvutils/version.cpp b/src/libelvutils/version.cpp index 7a812b91c..3dc38ce0f 100644 --- a/src/libelvutils/version.cpp +++ b/src/libelvutils/version.cpp @@ -1,6 +1,8 @@ // Version of libelvutils (see version.sh and CHANGELOG.md). A program can print it -// by declaring: extern const char ELVUTILS_VERSION_STRING[]; +// by declaring: extern "C" const char* elvutils_version(); #include "generated-elvutils-version.h" -extern const char ELVUTILS_VERSION_STRING[]; -const char ELVUTILS_VERSION_STRING[] = ELVUTILS_VERSION; +extern "C" const char* elvutils_version() +{ + return ELVUTILS_VERSION; +} diff --git a/src/libeq3config/version.cpp b/src/libeq3config/version.cpp index a808ba86d..a1d55d8a7 100644 --- a/src/libeq3config/version.cpp +++ b/src/libeq3config/version.cpp @@ -1,6 +1,8 @@ // Version of libeq3config (see version.sh and CHANGELOG.md). A program can print it -// by declaring: extern const char EQ3CONFIG_VERSION_STRING[]; +// by declaring: extern "C" const char* eq3config_version(); #include "generated-eq3config-version.h" -extern const char EQ3CONFIG_VERSION_STRING[]; -const char EQ3CONFIG_VERSION_STRING[] = EQ3CONFIG_VERSION; +extern "C" const char* eq3config_version() +{ + return EQ3CONFIG_VERSION; +} diff --git a/src/libhsscomm/version.cpp b/src/libhsscomm/version.cpp index 31debbfa5..000bc154e 100644 --- a/src/libhsscomm/version.cpp +++ b/src/libhsscomm/version.cpp @@ -1,6 +1,8 @@ // Version of libhsscomm (see version.sh and CHANGELOG.md). A program can print it -// by declaring: extern const char HSSCOMM_VERSION_STRING[]; +// by declaring: extern "C" const char* hsscomm_version(); #include "generated-hsscomm-version.h" -extern const char HSSCOMM_VERSION_STRING[]; -const char HSSCOMM_VERSION_STRING[] = HSSCOMM_VERSION; +extern "C" const char* hsscomm_version() +{ + return HSSCOMM_VERSION; +} From 457f243c117ee81d84e85955d5923e73dbffb9d5 Mon Sep 17 00:00:00 2001 From: Jens Maus Date: Mon, 2 Nov 2026 10:57:26 +0000 Subject: [PATCH 3/4] add a version to every program and library: show the library versions --version (and -v where the option is free: rfd, hs485d, multimacd, eq3configd, eq3configcmd, hs485dLoader, SetInterfaceClock) now also prints the versions of the OpenCCU-Base libraries the program calls, read from the loaded libraries. libXmlRpc gets xmlrpc_version() (its XMLRPC_VERSION stays "XMLRPC++ 0.12") and libxmlparser xmlparser_version(); every library declares its function in _version.h. hss_led, SetInterfaceClock and hs485dLoader no longer link libraries they do not call: libxmlparser, and libhsscomm for SetInterfaceClock. The changelogs of rfd and hs485d get an Unreleased entry for the new option. --- AGENTS.md | 12 +++++++--- src/SetInterfaceClock/CMakeLists.txt | 2 +- src/SetInterfaceClock/SetInterfaceClock.cpp | 13 ++++++++-- src/crypttool/crypttool.cpp | 12 ++++++++-- src/eq3configcmd/eq3configcmd.cpp | 6 +++-- src/eq3configd/main.cpp | 12 ++++++++-- src/hs485d/CHANGELOG.md | 8 +++++++ src/hs485d/hs485d.cpp | 22 +++++++++++++++++ src/hs485dLoader/CMakeLists.txt | 2 +- src/hs485dLoader/hs485dLoader.cpp | 12 ++++++++-- src/hss_led/CMakeLists.txt | 4 ++-- src/hss_led/LedCli.h | 8 +++++++ .../include/landeviceutils_version.h | 7 ++++++ src/libLanDeviceUtils/src/version.cpp | 5 ++-- .../include/unifiedlancomm_version.h | 7 ++++++ src/libUnifiedLanComm/src/version.cpp | 5 ++-- src/libXmlRpc/src/XmlRpcUtil.cpp | 8 ++++++- src/libXmlRpc/src/xmlrpc_version.h | 10 ++++++++ src/libelvutils/elvutils_version.h | 7 ++++++ src/libelvutils/version.cpp | 5 ++-- src/libeq3config/eq3config_version.h | 7 ++++++ src/libeq3config/version.cpp | 5 ++-- src/libhsscomm/hsscomm_version.h | 7 ++++++ src/libhsscomm/version.cpp | 5 ++-- src/libxmlparser/xmlParser.cpp | 6 +++++ src/libxmlparser/xmlparser_version.h | 10 ++++++++ src/multimacd/multimacd.cpp | 14 ++++++++++- src/rfd/CHANGELOG.md | 8 +++++++ src/rfd/rfd.cpp | 24 ++++++++++++++++++- 29 files changed, 223 insertions(+), 30 deletions(-) create mode 100644 src/libLanDeviceUtils/include/landeviceutils_version.h create mode 100644 src/libUnifiedLanComm/include/unifiedlancomm_version.h create mode 100644 src/libXmlRpc/src/xmlrpc_version.h create mode 100644 src/libelvutils/elvutils_version.h create mode 100644 src/libeq3config/eq3config_version.h create mode 100644 src/libhsscomm/hsscomm_version.h create mode 100644 src/libxmlparser/xmlparser_version.h diff --git a/AGENTS.md b/AGENTS.md index 2ba96280e..e7e279812 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -53,8 +53,9 @@ what you could and could not test. `libhsscomm`, `libelvutils`, `libLanDeviceUtils`, `libUnifiedLanComm`, `libeq3config`), in `MODULE_VERSION` (`eq3_char_loop`, `bcm2835_raw_uart`), in the Tcl package version (`tclrega`, `tclrpc`, `tcl_homematic`) or in the - library's own version (`XMLRPC_VERSION` of `libXmlRpc`, `@version` in - `xmlParser.h` of `libxmlparser`). + library's version header (`XMLRPC_VERSION_NUMBER` in `xmlrpc_version.h` of + `libXmlRpc`, `XMLPARSER_VERSION_NUMBER` in `xmlparser_version.h` of + `libxmlparser`, kept equal to `@version` in `xmlParser.h`). A user-visible change raises it (a fix the patch level, a new function the minor version), either in the same pull request or in a collected bump. CMake generates the header from `version.sh` with `openccu_version_header()`; @@ -62,7 +63,12 @@ what you could and could not test. `src//generated--version.h`, which is bumped together with `version.sh`. Never give the shared libraries a CMake `VERSION` or `SOVERSION`: their SONAME must stay the plain `lib.so`, which ReGaHss - and the OpenCCU packaging load. + and the OpenCCU packaging load. Each library returns its version from + `_version()` (declared in `_version.h`); a program's `--version` + (and `-v` where the option is free) prints its own version and the versions + of the OpenCCU-Base libraries whose functions it calls, read from the loaded + libraries (check with `nm -D --undefined-only`, not only the link line). + A program links only the OpenCCU-Base libraries whose functions it calls. - **Daemon changelogs:** a pull request with a user-visible change to `rfd` or `hs485d` (including changes of the libraries they are built with) adds an entry to `src//CHANGELOG.md` under `## Unreleased` (create the diff --git a/src/SetInterfaceClock/CMakeLists.txt b/src/SetInterfaceClock/CMakeLists.txt index b04cca6f1..bd88d14f4 100644 --- a/src/SetInterfaceClock/CMakeLists.txt +++ b/src/SetInterfaceClock/CMakeLists.txt @@ -7,6 +7,6 @@ target_include_directories(SetInterfaceClock PRIVATE "${CMAKE_SOURCE_DIR}/src/libelvutils" "${CMAKE_SOURCE_DIR}/src/libxmlparser" ) -target_link_libraries(SetInterfaceClock PRIVATE XmlRpc hsscomm xmlparser elvutils pthread crypto) +target_link_libraries(SetInterfaceClock PRIVATE XmlRpc elvutils pthread crypto) openccu_version_header(SetInterfaceClock SetInterfaceClock SETINTERFACECLOCK_VERSION) openccu_stage_target(SetInterfaceClock bin) diff --git a/src/SetInterfaceClock/SetInterfaceClock.cpp b/src/SetInterfaceClock/SetInterfaceClock.cpp index b1251e57b..61513fab9 100644 --- a/src/SetInterfaceClock/SetInterfaceClock.cpp +++ b/src/SetInterfaceClock/SetInterfaceClock.cpp @@ -17,6 +17,8 @@ #include #include #include "generated-SetInterfaceClock-version.h" +#include "xmlrpc_version.h" +#include "elvutils_version.h" void printUsage(); @@ -25,10 +27,17 @@ std::string readPortFromFile(const char* filename); using namespace XmlRpc; +static void printVersion() +{ + printf("SetInterfaceClock %s (%s)\n", SETINTERFACECLOCK_VERSION, __DATE__); + printf(" libXmlRpc %s\n", xmlrpc_version()); + printf(" libelvutils %s\n", elvutils_version()); +} + int main(int argc, char* argv[]) { - if(argc == 2 && strcmp(argv[1], "--version") == 0) { - printf("SetInterfaceClock %s (%s)\n", SETINTERFACECLOCK_VERSION, __DATE__); + if(argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { + printVersion(); return 0; } diff --git a/src/crypttool/crypttool.cpp b/src/crypttool/crypttool.cpp index 7fc9f0c5f..02edf1ac2 100644 --- a/src/crypttool/crypttool.cpp +++ b/src/crypttool/crypttool.cpp @@ -23,9 +23,16 @@ #include "crypttoolconfig.h" #include "generated-crypttool-version.h" +#include "elvutils_version.h" const char* defaultKey = "Markus is awesome"; +static void printVersion() +{ + printf("crypttool %s (%s)\n", CRYPTTOOL_VERSION, __DATE__); + printf(" libelvutils %s\n", elvutils_version()); +} + static void usage(const char* procname) { printf("crypttool %s (%s)\n\n", CRYPTTOOL_VERSION, __DATE__); @@ -48,6 +55,7 @@ static void usage(const char* procname) printf(" -i: key index for -S\n"); printf(" -y: log to syslog instead of console\n"); printf(" -l: set log level\n"); + printf(" --version: show the versions of crypttool and its libraries\n"); printf(" -f: path to crypttool configuration file\n"); if(logger) @@ -267,8 +275,8 @@ int get_index(crypttoolconfig& crypttoolconfig, int key_type) int main(int argc, char* argv[]) { - if(argc == 2 && strcmp(argv[1], "--version") == 0) { - printf("crypttool %s (%s)\n", CRYPTTOOL_VERSION, __DATE__); + if(argc == 2 && (strcmp(argv[1], "--version") == 0)) { + printVersion(); return 0; } diff --git a/src/eq3configcmd/eq3configcmd.cpp b/src/eq3configcmd/eq3configcmd.cpp index c50960fdd..dd060e34a 100644 --- a/src/eq3configcmd/eq3configcmd.cpp +++ b/src/eq3configcmd/eq3configcmd.cpp @@ -14,14 +14,16 @@ #include #include "generated-eq3configcmd-version.h" +#include "eq3config_version.h" void printUsage(); void removeLeadingPathseperators(std::string& filename); int main(int argc, char** argv) { - if(argc == 2 && strcmp(argv[1], "--version") == 0) { - std::cout << "eq3configcmd " EQ3CONFIGCMD_VERSION " (" __DATE__ ")" << std::endl; + if(argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { + std::cout << "eq3configcmd " EQ3CONFIGCMD_VERSION " (" __DATE__ ")" << std::endl + << " libeq3config " << eq3config_version() << std::endl; return 0; } diff --git a/src/eq3configd/main.cpp b/src/eq3configd/main.cpp index 13cb0faf3..bb5ed9cfb 100644 --- a/src/eq3configd/main.cpp +++ b/src/eq3configd/main.cpp @@ -29,6 +29,7 @@ #include "include/udpframe.h" #include "generated-eq3configd-version.h" +#include "elvutils_version.h" #include "include/networkconfig.h" #include @@ -58,6 +59,12 @@ const uint8_t UDP_CRYPT_RANDOM_SIZE = 16; const uint8_t UDP_CRYPT_SIGNATURE_SIZE = 16; const uint8_t UDP_CRYPT_SIGNATURE[UDP_CRYPT_SIGNATURE_SIZE] = "eQ-3__UDP-Crypt"; +static void printVersion() +{ + printf("eq3configd %s (%s)\n", EQ3CONFIGD_VERSION, __DATE__); + printf(" libelvutils %s\n", elvutils_version()); +} + static void usage(const char* procname) { printf("eq3configd %s (%s)\n\n", EQ3CONFIGD_VERSION, __DATE__); @@ -67,6 +74,7 @@ static void usage(const char* procname) printf(" -t: device type identifier to publish\n"); printf(" -c: log to console instead of syslog\n"); printf(" -l: set log level\n"); + printf(" -v, --version: show the versions of eq3configd and its libraries\n"); } int main(int argc, char* argv[]) @@ -86,8 +94,8 @@ int main(int argc, char* argv[]) Logger::LogLevel loglevel=Logger::LOG_INFO; std::string deviceType = ""; - if(argc == 2 && strcmp(argv[1], "--version") == 0) { - printf("eq3configd %s (%s)\n", EQ3CONFIGD_VERSION, __DATE__); + if(argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { + printVersion(); return 0; } diff --git a/src/hs485d/CHANGELOG.md b/src/hs485d/CHANGELOG.md index 28c2289b1..a50bdbb8d 100644 --- a/src/hs485d/CHANGELOG.md +++ b/src/hs485d/CHANGELOG.md @@ -9,6 +9,14 @@ Changes not yet released are collected under `Unreleased` and get the version and date with the next version bump (`version.sh` and `generated-hs485d-version.h`). +## Unreleased + +* add the option `-v` / `--version`, which prints the version of hs485d and the + versions of the OpenCCU-Base libraries it uses (libXmlRpc, libxmlparser, + libhsscomm, libelvutils, libLanDeviceUtils, libUnifiedLanComm), as reported + by the loaded libraries. The libraries now have versions of their own. + ([#294](https://github.com/OpenCCU/OpenCCU-Base/pull/294)) + ## 1.4.0 (2026-11-01) * add the RPC method `restoreConfigToDevice`, which writes the configuration diff --git a/src/hs485d/hs485d.cpp b/src/hs485d/hs485d.cpp index 1c4d1846c..12221e6e8 100644 --- a/src/hs485d/hs485d.cpp +++ b/src/hs485d/hs485d.cpp @@ -56,6 +56,12 @@ char buffer[128]; #include #include "generated-hs485d-version.h" +#include "xmlrpc_version.h" +#include "xmlparser_version.h" +#include "hsscomm_version.h" +#include "elvutils_version.h" +#include "landeviceutils_version.h" +#include "unifiedlancomm_version.h" using namespace XmlRpc; @@ -82,6 +88,17 @@ static void sigterm_handler(int sig) run=false; } +static void printVersion() +{ + std::cout << "hs485d " << HS485D_VERSION << " (" << __DATE__ << ")" << std::endl + << " libXmlRpc " << xmlrpc_version() << std::endl + << " libxmlparser " << xmlparser_version() << std::endl + << " libhsscomm " << hsscomm_version() << std::endl + << " libelvutils " << elvutils_version() << std::endl + << " libLanDeviceUtils " << landeviceutils_version() << std::endl + << " libUnifiedLanComm " << unifiedlancomm_version() << std::endl; +} + static void usage(const char* procname) { std::cout << "HS485D " << HS485D_VERSION << " (" << __DATE__ << ")" << std::endl @@ -96,6 +113,7 @@ static void usage(const char* procname) << " -s: HM2 LGW serial number" << std::endl << " -i: HM2 LGW Interface Number. (From /etc/config/hs485d.conf) Use 0 for [Interface 0]" << std::endl << " -k: Encryption Key. (Only valid for HM2 LGW.)" << std::endl + << " -v, --version: show the versions of hs485d and its libraries" << std::endl << std::endl << "Examples for HM2 Wired LGW:" << std::endl << std::endl @@ -146,6 +164,10 @@ int main(int argc, char* argv[]) const struct rlimit rl={RLIM_INFINITY, RLIM_INFINITY}; setrlimit(RLIMIT_CORE, &rl); #endif + if(argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { + printVersion(); + return 0; + } for(int i=1;ii+1){ diff --git a/src/hs485dLoader/CMakeLists.txt b/src/hs485dLoader/CMakeLists.txt index 3d4e9ed47..a75d85b58 100644 --- a/src/hs485dLoader/CMakeLists.txt +++ b/src/hs485dLoader/CMakeLists.txt @@ -9,7 +9,7 @@ target_include_directories(hs485dLoader PRIVATE "${CMAKE_SOURCE_DIR}/src/libelvutils" "${CMAKE_SOURCE_DIR}/src/libxmlparser" ) -target_link_libraries(hs485dLoader PRIVATE pthread m c elvutils xmlparser) +target_link_libraries(hs485dLoader PRIVATE pthread m c elvutils) openccu_version_header(hs485dLoader hs485dLoader HS485DLOADER_VERSION) openccu_stage_target(hs485dLoader bin) diff --git a/src/hs485dLoader/hs485dLoader.cpp b/src/hs485dLoader/hs485dLoader.cpp index b13220c1b..237dbfc5c 100644 --- a/src/hs485dLoader/hs485dLoader.cpp +++ b/src/hs485dLoader/hs485dLoader.cpp @@ -20,6 +20,7 @@ #include #include #include "generated-hs485dLoader-version.h" +#include "elvutils_version.h" @@ -46,6 +47,12 @@ std::string retrieveXmlRpcPort(); std::string trim(const std::string& str); //Implementations +static void printVersion() +{ + printf("hs485dLoader %s (%s)\n", HS485DLOADER_VERSION, __DATE__); + printf(" libelvutils %s\n", elvutils_version()); +} + int main(int argc, char** argv) { int logLevel = 5; @@ -55,8 +62,8 @@ int main(int argc, char** argv) bool writeInterfacesXML = true; bool startAsDaemon = true; std::string interfacesXmlPath("/etc/config/InterfacesList.xml"); - if(argc == 2 && strcmp(argv[1], "--version") == 0) { - printf("hs485dLoader %s (%s)\n", HS485DLOADER_VERSION, __DATE__); + if(argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { + printVersion(); return 0; } //Parse args @@ -342,4 +349,5 @@ void printUsage() printf("\t-dw: Do not write /etc/config/InterfacesList.xml, just start hs485d\n"); printf("\t-dd: Do not start as daemon process.\n"); printf("\t-ilp: Path to InterfacesList.xml (default is /etc/config/InterfacesList.xml)\n"); + printf("\t-v, --version: Show the versions of hs485dLoader and its libraries\n"); } diff --git a/src/hss_led/CMakeLists.txt b/src/hss_led/CMakeLists.txt index 74110d776..cebde4c2e 100644 --- a/src/hss_led/CMakeLists.txt +++ b/src/hss_led/CMakeLists.txt @@ -23,14 +23,14 @@ add_executable(hss_led hss_led_util.cpp ) target_compile_features(hss_led PRIVATE cxx_std_11) -target_compile_definitions(hss_led PRIVATE _TIME_BITS=64 _FILE_OFFSET_BITS=64 PLATFORM_CCU3) +target_compile_definitions(hss_led PRIVATE _TIME_BITS=64 _FILE_OFFSET_BITS=64 PLATFORM_CCU3 HSS_LED_STATUS_MONITOR) target_compile_options(hss_led PRIVATE -Wall) target_include_directories(hss_led PRIVATE "${CMAKE_SOURCE_DIR}/src/libelvutils" "${CMAKE_SOURCE_DIR}/src/libxmlparser" "${CMAKE_SOURCE_DIR}/src/libXmlRpc/src" ) -target_link_libraries(hss_led PRIVATE XmlRpc elvutils xmlparser pthread) +target_link_libraries(hss_led PRIVATE XmlRpc elvutils pthread) endif() openccu_version_header(hss_led hss_led HSS_LED_VERSION) set_property(TARGET hss_led PROPERTY OPENCCU_RUNTIME_ALIASES hss_ledctl) diff --git a/src/hss_led/LedCli.h b/src/hss_led/LedCli.h index 3ecfa66e3..fd16148d9 100644 --- a/src/hss_led/LedCli.h +++ b/src/hss_led/LedCli.h @@ -3,6 +3,10 @@ #define OPENCCU_LED_CLI_H #include #include "generated-hss_led-version.h" +#ifdef HSS_LED_STATUS_MONITOR +#include "elvutils_version.h" +#include "xmlrpc_version.h" +#endif namespace LedCli { static const unsigned slowMs = 500; @@ -12,6 +16,10 @@ inline void version(std::ostream& out, const char* program, bool recovery = fals out << program << " " HSS_LED_VERSION " (built " << __DATE__ << " " << __TIME__ << ")"; if (recovery) out << " [recovery]"; out << '\n'; +#ifdef HSS_LED_STATUS_MONITOR + out << " libXmlRpc " << xmlrpc_version() << '\n' + << " libelvutils " << elvutils_version() << '\n'; +#endif } inline void daemonHelp(std::ostream& out, bool recovery = false) { diff --git a/src/libLanDeviceUtils/include/landeviceutils_version.h b/src/libLanDeviceUtils/include/landeviceutils_version.h new file mode 100644 index 000000000..754703749 --- /dev/null +++ b/src/libLanDeviceUtils/include/landeviceutils_version.h @@ -0,0 +1,7 @@ +// Version of libLanDeviceUtils as built into the library that is loaded at run time. +#ifndef LANDEVICEUTILS_VERSION_H +#define LANDEVICEUTILS_VERSION_H + +extern "C" const char* landeviceutils_version(); + +#endif diff --git a/src/libLanDeviceUtils/src/version.cpp b/src/libLanDeviceUtils/src/version.cpp index b2cfec819..19f0bb114 100644 --- a/src/libLanDeviceUtils/src/version.cpp +++ b/src/libLanDeviceUtils/src/version.cpp @@ -1,5 +1,6 @@ -// Version of libLanDeviceUtils (see version.sh and CHANGELOG.md). A program can print it -// by declaring: extern "C" const char* landeviceutils_version(); +// Version of libLanDeviceUtils (see version.sh and CHANGELOG.md). +// Declared in landeviceutils_version.h. +#include "landeviceutils_version.h" #include "generated-LanDeviceUtils-version.h" extern "C" const char* landeviceutils_version() diff --git a/src/libUnifiedLanComm/include/unifiedlancomm_version.h b/src/libUnifiedLanComm/include/unifiedlancomm_version.h new file mode 100644 index 000000000..2dfcc353a --- /dev/null +++ b/src/libUnifiedLanComm/include/unifiedlancomm_version.h @@ -0,0 +1,7 @@ +// Version of libUnifiedLanComm as built into the library that is loaded at run time. +#ifndef UNIFIEDLANCOMM_VERSION_H +#define UNIFIEDLANCOMM_VERSION_H + +extern "C" const char* unifiedlancomm_version(); + +#endif diff --git a/src/libUnifiedLanComm/src/version.cpp b/src/libUnifiedLanComm/src/version.cpp index 75a169f88..ebbe70e63 100644 --- a/src/libUnifiedLanComm/src/version.cpp +++ b/src/libUnifiedLanComm/src/version.cpp @@ -1,5 +1,6 @@ -// Version of libUnifiedLanComm (see version.sh and CHANGELOG.md). A program can print it -// by declaring: extern "C" const char* unifiedlancomm_version(); +// Version of libUnifiedLanComm (see version.sh and CHANGELOG.md). +// Declared in unifiedlancomm_version.h. +#include "unifiedlancomm_version.h" #include "generated-UnifiedLanComm-version.h" extern "C" const char* unifiedlancomm_version() diff --git a/src/libXmlRpc/src/XmlRpcUtil.cpp b/src/libXmlRpc/src/XmlRpcUtil.cpp index 61f5f2d33..5243d4da6 100644 --- a/src/libXmlRpc/src/XmlRpcUtil.cpp +++ b/src/libXmlRpc/src/XmlRpcUtil.cpp @@ -13,6 +13,7 @@ #endif #include "XmlRpc.h" +#include "xmlrpc_version.h" using namespace XmlRpc; @@ -24,7 +25,12 @@ using namespace XmlRpc; #endif // Version id -const char XmlRpc::XMLRPC_VERSION[] = "XMLRPC++ 0.12"; +const char XmlRpc::XMLRPC_VERSION[] = "XMLRPC++ " XMLRPC_VERSION_NUMBER; + +extern "C" const char* xmlrpc_version() +{ + return XMLRPC_VERSION_NUMBER; +} // Default log verbosity: 0 for no messages through 5 (writes everything) int XmlRpcLogHandler::_verbosity = 0; diff --git a/src/libXmlRpc/src/xmlrpc_version.h b/src/libXmlRpc/src/xmlrpc_version.h new file mode 100644 index 000000000..f4fa0d23e --- /dev/null +++ b/src/libXmlRpc/src/xmlrpc_version.h @@ -0,0 +1,10 @@ +// Version of libXmlRpc as built into the library that is loaded at run time. +#ifndef XMLRPC_VERSION_H +#define XMLRPC_VERSION_H + +extern "C" const char* xmlrpc_version(); + +// Also part of XmlRpc::XMLRPC_VERSION ("XMLRPC++ "). +#define XMLRPC_VERSION_NUMBER "0.12" + +#endif diff --git a/src/libelvutils/elvutils_version.h b/src/libelvutils/elvutils_version.h new file mode 100644 index 000000000..2558eb435 --- /dev/null +++ b/src/libelvutils/elvutils_version.h @@ -0,0 +1,7 @@ +// Version of libelvutils as built into the library that is loaded at run time. +#ifndef ELVUTILS_VERSION_H +#define ELVUTILS_VERSION_H + +extern "C" const char* elvutils_version(); + +#endif diff --git a/src/libelvutils/version.cpp b/src/libelvutils/version.cpp index 3dc38ce0f..2b6920b29 100644 --- a/src/libelvutils/version.cpp +++ b/src/libelvutils/version.cpp @@ -1,5 +1,6 @@ -// Version of libelvutils (see version.sh and CHANGELOG.md). A program can print it -// by declaring: extern "C" const char* elvutils_version(); +// Version of libelvutils (see version.sh and CHANGELOG.md). +// Declared in elvutils_version.h. +#include "elvutils_version.h" #include "generated-elvutils-version.h" extern "C" const char* elvutils_version() diff --git a/src/libeq3config/eq3config_version.h b/src/libeq3config/eq3config_version.h new file mode 100644 index 000000000..5c31ab5bd --- /dev/null +++ b/src/libeq3config/eq3config_version.h @@ -0,0 +1,7 @@ +// Version of libeq3config as built into the library that is loaded at run time. +#ifndef EQ3CONFIG_VERSION_H +#define EQ3CONFIG_VERSION_H + +extern "C" const char* eq3config_version(); + +#endif diff --git a/src/libeq3config/version.cpp b/src/libeq3config/version.cpp index a1d55d8a7..bafc7df09 100644 --- a/src/libeq3config/version.cpp +++ b/src/libeq3config/version.cpp @@ -1,5 +1,6 @@ -// Version of libeq3config (see version.sh and CHANGELOG.md). A program can print it -// by declaring: extern "C" const char* eq3config_version(); +// Version of libeq3config (see version.sh and CHANGELOG.md). +// Declared in eq3config_version.h. +#include "eq3config_version.h" #include "generated-eq3config-version.h" extern "C" const char* eq3config_version() diff --git a/src/libhsscomm/hsscomm_version.h b/src/libhsscomm/hsscomm_version.h new file mode 100644 index 000000000..6500efd6f --- /dev/null +++ b/src/libhsscomm/hsscomm_version.h @@ -0,0 +1,7 @@ +// Version of libhsscomm as built into the library that is loaded at run time. +#ifndef HSSCOMM_VERSION_H +#define HSSCOMM_VERSION_H + +extern "C" const char* hsscomm_version(); + +#endif diff --git a/src/libhsscomm/version.cpp b/src/libhsscomm/version.cpp index 000bc154e..f1c2082f5 100644 --- a/src/libhsscomm/version.cpp +++ b/src/libhsscomm/version.cpp @@ -1,5 +1,6 @@ -// Version of libhsscomm (see version.sh and CHANGELOG.md). A program can print it -// by declaring: extern "C" const char* hsscomm_version(); +// Version of libhsscomm (see version.sh and CHANGELOG.md). +// Declared in hsscomm_version.h. +#include "hsscomm_version.h" #include "generated-hsscomm-version.h" extern "C" const char* hsscomm_version() diff --git a/src/libxmlparser/xmlParser.cpp b/src/libxmlparser/xmlParser.cpp index fa416554b..560b26630 100644 --- a/src/libxmlparser/xmlParser.cpp +++ b/src/libxmlparser/xmlParser.cpp @@ -69,6 +69,7 @@ #include #include #include +#include "xmlparser_version.h" #include "xmlParser.h" //#ifdef WIN32 @@ -2217,3 +2218,8 @@ XMLNode XMLNode::getChildNode (int i) { if (!d) return emptyXMLNode; i char XMLNode::isDeclaration( ) { if (!d) return 0; return d->isDeclaration; } char XMLNode::isEmpty ( ) { return (d==NULL); } int XMLNode::nElement ( ) { if (!d) return 0; return d->nChild+d->nText+d->nClear+d->nAttribute; } + +extern "C" const char* xmlparser_version() +{ + return XMLPARSER_VERSION_NUMBER; +} diff --git a/src/libxmlparser/xmlparser_version.h b/src/libxmlparser/xmlparser_version.h new file mode 100644 index 000000000..7ee1d6ef7 --- /dev/null +++ b/src/libxmlparser/xmlparser_version.h @@ -0,0 +1,10 @@ +// Version of libxmlparser as built into the library that is loaded at run time. +#ifndef XMLPARSER_VERSION_H +#define XMLPARSER_VERSION_H + +extern "C" const char* xmlparser_version(); + +// Keep in sync with "@version" in xmlParser.h. +#define XMLPARSER_VERSION_NUMBER "1.14" + +#endif diff --git a/src/multimacd/multimacd.cpp b/src/multimacd/multimacd.cpp index 7897fbdcc..3901e11b2 100644 --- a/src/multimacd/multimacd.cpp +++ b/src/multimacd/multimacd.cpp @@ -23,6 +23,7 @@ #endif #include "generated-multimacd-version.h" +#include "elvutils_version.h" static const char* CONFIG_DEFAULTS[] = { "Coprocessor Device Path", "/dev/mxs_auart_raw.0", @@ -84,6 +85,12 @@ void installSignalHandlers() } +static void printVersion() +{ + std::cout << "multimacd " << MULTIMACD_VERSION << " (" << __DATE__ << ")" << std::endl + << " libelvutils " << elvutils_version() << std::endl; +} + static void usage(const char* procname) { std::cout << "multimacd " << MULTIMACD_VERSION << " (" << __DATE__ << ")" << std::endl @@ -93,7 +100,8 @@ static void usage(const char* procname) << " -c: log to console instead of syslog" << std::endl << " -l: set log level" << std::endl << " -p: specify coprocessor device node" << std::endl - << " -d: run as daemon/service" << std::endl; + << " -d: run as daemon/service" << std::endl + << " -v, --version: show the versions of multimacd and its libraries" << std::endl; if(logger) delete logger; @@ -165,6 +173,10 @@ int main(int argc, char **argv) installSignalHandlers(); + if(argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { + printVersion(); + return 0; + } for(int i=1;ii+1){ diff --git a/src/rfd/CHANGELOG.md b/src/rfd/CHANGELOG.md index 847cdfb68..38f2618c6 100644 --- a/src/rfd/CHANGELOG.md +++ b/src/rfd/CHANGELOG.md @@ -8,6 +8,14 @@ Changes not yet released are collected under `Unreleased` and get the version and date with the next version bump (`version.sh` and `generated-rfd-version.h`). +## Unreleased + +* add the option `-v` / `--version`, which prints the version of rfd and the + versions of the OpenCCU-Base libraries it uses (libXmlRpc, libxmlparser, + libhsscomm, libelvutils, libLanDeviceUtils, libUnifiedLanComm), as reported + by the loaded libraries. The libraries now have versions of their own. + ([#294](https://github.com/OpenCCU/OpenCCU-Base/pull/294)) + ## 2.6.8 (2026-11-01) * fix a request to the radio module getting the answer of another one: when diff --git a/src/rfd/rfd.cpp b/src/rfd/rfd.cpp index 356d5ac67..05d6c9c94 100644 --- a/src/rfd/rfd.cpp +++ b/src/rfd/rfd.cpp @@ -57,6 +57,12 @@ char buffer[128]; #include #include "generated-rfd-version.h" +#include "xmlrpc_version.h" +#include "xmlparser_version.h" +#include "hsscomm_version.h" +#include "elvutils_version.h" +#include "landeviceutils_version.h" +#include "unifiedlancomm_version.h" using namespace XmlRpc; @@ -132,6 +138,17 @@ static const char* CONFIG_FILENAMES[] = { NULL }; +static void printVersion() +{ + std::cout << "rfd " << RFD_VERSION << " (" << __DATE__ << ")" << std::endl + << " libXmlRpc " << xmlrpc_version() << std::endl + << " libxmlparser " << xmlparser_version() << std::endl + << " libhsscomm " << hsscomm_version() << std::endl + << " libelvutils " << elvutils_version() << std::endl + << " libLanDeviceUtils " << landeviceutils_version() << std::endl + << " libUnifiedLanComm " << unifiedlancomm_version() << std::endl; +} + static void usage(const char* procname) { std::cout << "RFD " << RFD_VERSION << " (" << __DATE__ << ")" << std::endl @@ -151,7 +168,8 @@ static void usage(const char* procname) << " -f: use alternate config file" << std::endl << " -c: log to console instead of syslog" << std::endl << " -l: set log level" << std::endl - << " -s: sniffing mode" << std::endl; + << " -s: sniffing mode" << std::endl + << " -v, --version: show the versions of rfd and its libraries" << std::endl; if(logger) delete logger; @@ -200,6 +218,10 @@ int main(int argc, char* argv[]) const struct rlimit rl={RLIM_INFINITY, RLIM_INFINITY}; setrlimit(RLIMIT_CORE, &rl); #endif + if(argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { + printVersion(); + return 0; + } for(int i=1;ii+1){ From 1c532eddb6c7bb9115ebd28e0822f141da8ef40e Mon Sep 17 00:00:00 2001 From: Jens Maus Date: Mon, 2 Nov 2026 11:01:51 +0000 Subject: [PATCH 4/4] ssdpd: take -v/--version only as the single argument Like the other programs, ssdpd now prints its version only when -v or --version is its only argument. --- src/ssdpd/ssdpd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ssdpd/ssdpd.cpp b/src/ssdpd/ssdpd.cpp index a0d73a870..7fc569be5 100644 --- a/src/ssdpd/ssdpd.cpp +++ b/src/ssdpd/ssdpd.cpp @@ -342,7 +342,7 @@ static std::string getSerialNum() { int main(int argc, char ** argv) { char buffer[2048]; - if(argc > 1 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { + if(argc == 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)) { printf("ssdpd %s (%s)\n", SSDPD_VERSION, __DATE__); return 0; }