[posix] add --version to ot-ctl, ot-daemon and ot-cli (#13424)

The POSIX binaries cannot report their own version. ot-daemon and ot-cli
only log it to syslog at startup, and ot-ctl has no version output at
all: `ot-ctl version` queries the daemon, so it needs one running and
reports the daemon's version rather than the client's.

This also makes the binaries awkward to package, as build systems
commonly probe an installed executable with `--version` to check the
version actually shipped.

Add -V/--version to all three. ot-daemon and ot-cli, which share
src/posix/main.c, print otGetVersionString(), the same string already
logged at startup. ot-ctl is a standalone client that does not link the
core library, so it prints PACKAGE_VERSION, which is its own build
version and is available without a running daemon.

-V rather than -v, as -v is already --verbose in main.c; using the same
letter across all three keeps the binaries consistent.

ot-ctl gains the PACKAGE_VERSION compile definition, matching how src/cli
and src/ncp already receive it. For build environments other than CMake
and GN, which define the macro themselves, openthread-posix-config.h
falls back to "unknown" so the client stays compilable.

    $ ot-ctl --version
    thread-reference-20250612-1379-g221777306
    $ ot-daemon --version
    OPENTHREAD/thread-reference-20250612-1379-g221777306; POSIX; Jul 29 2026 20:19:02

Assisted-By: Claude Fable 5
This commit is contained in:
Christian Glombek
2026-07-30 17:07:15 -07:00
committed by GitHub
parent 3cad859c6d
commit 8fb0bdd858
4 changed files with 32 additions and 4 deletions
+9 -2
View File
@@ -207,10 +207,12 @@ exit:
constexpr char kOptInterfaceName = 'I';
constexpr char kOptHelp = 'h';
constexpr char kOptVersion = 'V';
const struct option kOptions[] = {
{"interface-name", required_argument, nullptr, kOptInterfaceName},
{"help", no_argument, nullptr, kOptHelp},
{"version", no_argument, nullptr, kOptVersion},
{nullptr, 0, nullptr, 0},
};
@@ -221,7 +223,8 @@ void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
" %s [Options] [--] ...\n"
"Options:\n"
" -h --help Display this usage information.\n"
" -I --interface-name name Thread network interface name.\n",
" -I --interface-name name Thread network interface name.\n"
" -V --version Display version information.\n",
aProgramName);
exit(aExitCode);
}
@@ -237,7 +240,7 @@ Config ParseArg(int &aArgCount, char **&aArgVector)
optind = 1;
for (int index, option; (option = getopt_long(aArgCount, aArgVector, "+I:h", kOptions, &index)) != -1;)
for (int index, option; (option = getopt_long(aArgCount, aArgVector, "+I:hV", kOptions, &index)) != -1;)
{
switch (option)
{
@@ -247,6 +250,10 @@ Config ParseArg(int &aArgCount, char **&aArgVector)
case kOptHelp:
PrintUsage(aArgVector[0], stdout, OT_EXIT_SUCCESS);
break;
case kOptVersion:
printf("%s\n", PACKAGE_VERSION);
exit(OT_EXIT_SUCCESS);
break;
default:
PrintUsage(aArgVector[0], stderr, OT_EXIT_FAILURE);
break;
+3
View File
@@ -67,6 +67,9 @@ target_compile_definitions(ot-ctl PRIVATE
$<$<BOOL:${READLINE}>:HAVE_LIB$<UPPER_CASE:${OT_READLINE}>=1>)
endif()
target_compile_definitions(ot-ctl PRIVATE
"PACKAGE_VERSION=\"${OT_PACKAGE_VERSION}\"")
target_compile_options(ot-ctl PRIVATE
${OT_CFLAGS}
)
+9 -2
View File
@@ -135,6 +135,7 @@ enum
OT_POSIX_OPT_PERSISTENT_INTERFACE = 'p',
OT_POSIX_OPT_TIME_SPEED = 's',
OT_POSIX_OPT_VERBOSE = 'v',
OT_POSIX_OPT_VERSION = 'V',
OT_POSIX_OPT_SHORT_MAX = 128,
@@ -163,6 +164,7 @@ static const struct option kOptions[] = {
{"tun-device", required_argument, NULL, OT_POSIX_OPT_TUN_DEVICE},
#endif
{"verbose", no_argument, NULL, OT_POSIX_OPT_VERBOSE},
{"version", no_argument, NULL, OT_POSIX_OPT_VERSION},
{0, 0, 0, 0}};
static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
@@ -184,7 +186,8 @@ static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
" --radio-version Print radio firmware version.\n"
" -p --persistent-interface Persistent the created thread network interface\n"
" -s --time-speed factor Time speed up factor.\n"
" -v --verbose Also log to stderr.\n",
" -v --verbose Also log to stderr.\n"
" -V --version Display version information.\n",
aProgramName);
#ifdef SIGRTMIN
fprintf(aStream,
@@ -217,7 +220,7 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
while (true)
{
int index = 0;
int option = getopt_long(aArgCount, aArgVector, "B:d:hI:nps:v", kOptions, &index);
int option = getopt_long(aArgCount, aArgVector, "B:d:hI:nps:vV", kOptions, &index);
if (option == -1)
{
@@ -260,6 +263,10 @@ static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
case OT_POSIX_OPT_VERBOSE:
aConfig->mIsVerbose = true;
break;
case OT_POSIX_OPT_VERSION:
printf("%s\n", otGetVersionString());
exit(OT_EXIT_SUCCESS);
break;
case OT_POSIX_OPT_RADIO_VERSION:
aConfig->mPrintRadioVersion = true;
break;
@@ -41,6 +41,17 @@
* This file includes the POSIX platform-specific configurations.
*/
/**
* @def PACKAGE_VERSION
*
* The version string reported by `ot-ctl --version`. The OpenThread build
* systems define it; this fallback keeps the client compiling in custom
* build environments that do not.
*/
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "unknown"
#endif
/**
* @def OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
*