diff --git a/CMakeLists.txt b/CMakeLists.txt index 67e384935..f310d4663 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ include(FindPackageMessage) include(GNUInstallDirs) set(CONFIG_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}") +set(AVRDUDE_BUILDSYSTEM "cmake") set(AVRDUDE_FULL_VERSION ${CMAKE_PROJECT_VERSION}) # ===================================== diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 72028dbe1..79d4dd7ac 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -179,6 +179,7 @@ set(SOURCES avrpart.c bitbang.c bitbang.h + buildinfo.c buspirate.c buspirate.h butterfly.c diff --git a/src/Makefile.am b/src/Makefile.am index 9d0833f23..c074eaf80 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -106,6 +106,7 @@ libavrdude_la_SOURCES = \ avr_opcodes.c \ bitbang.c \ bitbang.h \ + buildinfo.c \ buspirate.c \ buspirate.h \ butterfly.c \ diff --git a/src/buildinfo.c b/src/buildinfo.c new file mode 100644 index 000000000..03cedeb77 --- /dev/null +++ b/src/buildinfo.c @@ -0,0 +1,108 @@ +#include + +#include + + +const avr_buildinfo libavrdude_buildinfo = { + "libavrdude", AVRDUDE_FULL_VERSION, + { + {"buildsystem", AVRDUDE_BUILDSYSTEM}, + + {"libelf", +#ifdef HAVE_LIBELF + "yes" +#else + NULL +#endif + }, + + {"libusb", +#ifdef HAVE_LIBUSB + "yes" +#else + NULL +#endif + }, + + {"libusb_1_0", +#ifdef HAVE_LIBUSB_1_0 + "yes" +#else + NULL +#endif + }, + + {"libhidapi", +#ifdef HAVE_LIBHIDAPI + "yes" +#else + NULL +#endif + }, + + {"libhid", +#ifdef HAVE_LIBHID + "yes" +#else + NULL +#endif + }, + + {"libftdi", +#ifdef HAVE_LIBFTDI + "yes" +#else + NULL +#endif + }, + + {"libftdi1", +#ifdef HAVE_LIBFTDI1 + "yes" +#else + NULL +#endif + }, + + {"libreadline", +#ifdef HAVE_LIBREADLINE + "yes" +#else + NULL +#endif + }, + + {"libserialport", +#ifdef HAVE_LIBSERIALPORT + "yes" +#else + NULL +#endif + }, + + {"parport", +#ifdef HAVE_PARPORT + "yes" +#else + NULL +#endif + }, + + {"linuxgpio", +#ifdef HAVE_LINUXGPIO + "yes" +#else + NULL +#endif + }, + + {"linuxspi", +#ifdef HAVE_LINUXSPI + "yes" +#else + NULL +#endif + }, + {NULL, NULL}, + }, +}; diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in index f11ca00cc..e3e829ab3 100644 --- a/src/cmake_config.h.in +++ b/src/cmake_config.h.in @@ -21,6 +21,7 @@ #endif #define AVRDUDE_FULL_VERSION "@AVRDUDE_FULL_VERSION@" +#define AVRDUDE_BUILDSYSTEM "@AVRDUDE_BUILDSYSTEM@" /* Options */ diff --git a/src/configure.ac b/src/configure.ac index 91f6a4459..1d5f0e167 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -91,6 +91,9 @@ AC_DEFINE_UNQUOTED([AVRDUDE_FULL_VERSION], ["$AVRDUDE_FULL_VERSION"], [The full avrdude version as displayed in -? and avrdude.conf]) AC_SUBST([AVRDUDE_FULL_VERSION]) +AC_DEFINE_UNQUOTED([AVRDUDE_BUILDSYSTEM], ["autotools"], + [The buildsystem used to build avrdude]) + # Define libavrdude libtool version from cmake libavrdude information dnl diff --git a/src/libavrdude.h b/src/libavrdude.h index 9bb35b991..81a459042 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -1202,6 +1202,21 @@ extern "C" { int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p); int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p); + +typedef struct avr_buildinfo_item { + const char *const key; + const char *const value; +} avr_buildinfo_item; + +typedef struct avr_buildinfo { + const char *const name; + const char *const version; + avr_buildinfo_item items[]; +} avr_buildinfo; + +extern const avr_buildinfo libavrdude_buildinfo; + + #ifdef __cplusplus } #endif diff --git a/src/main.c b/src/main.c index cec73e250..5517b9f95 100644 --- a/src/main.c +++ b/src/main.c @@ -48,6 +48,8 @@ #include #endif +#include + #include "avrdude.h" #include "libavrdude.h" #include "config.h" @@ -228,6 +230,50 @@ const char *pgmid; // Programmer -c string static char usr_config[PATH_MAX]; // Per-user config file + +static +const avr_buildinfo avrdude_buildinfo = { + "avrdude", AVRDUDE_FULL_VERSION, + { + {"buildsystem", AVRDUDE_BUILDSYSTEM}, + {NULL, NULL}, + } +}; + + +static void print_buildinfo(const avr_buildinfo *const buildinfo) +{ + msg_info(" * %s %s\n", + buildinfo->name, buildinfo->version); + + for (unsigned int i=0; buildinfo->items[i].key; ++i) { + if (buildinfo->items[i].value) { + msg_info(" %3u. %s: %s\n", i, + buildinfo->items[i].key, buildinfo->items[i].value); + } + } +} + + +static void print_version_message(void) +{ + msg_info("avrdude (...) %s\n", AVRDUDE_FULL_VERSION); + msg_info("Copyright (C) ...2024...\n"); + msg_info("License GPL...\n"); + msg_info("This is free software...\n"); + + const avr_buildinfo *const all_buildinfos[] = { + &avrdude_buildinfo, + &libavrdude_buildinfo, + NULL, + }; + + for (unsigned int i=0; all_buildinfos[i]; ++i) { + print_buildinfo(all_buildinfos[i]); + } +} + + // Usage message static void usage(void) { char *home = getenv("HOME"); @@ -269,7 +315,8 @@ static void usage(void) { " -v Verbose output; -v -v for more\n" " -q Quell progress output; -q -q for less\n" " -l logfile Use logfile rather than stderr for diagnostics\n" - " -? Display this usage\n" + " --version Display build and version information\n" + " -? | --help Display this usage\n" "\navrdude version %s, https://github.com/avrdudes/avrdude\n", progname, strlen(cfg) < 24? "config file ": "", cfg, AVRDUDE_FULL_VERSION); @@ -814,7 +861,14 @@ int main(int argc, char *argv[]) { #endif // Process command line arguments - while((ch = getopt(argc, argv, "?Ab:B:c:C:DeE:Fi:l:nNp:OP:qrtT:U:vVx:")) != -1) { +#define LONGOPT_VERSION 0x2342 + struct option longopts[] = { + {"help", no_argument, NULL, '?'}, + {"version", no_argument, NULL, LONGOPT_VERSION}, + {NULL, 0, NULL, 0} + }; + while((ch = getopt_long(argc, argv, "?Ab:B:c:C:DeE:Fi:l:nNp:OP:qrtT:U:vVx:", + longopts, NULL)) != -1) { switch(ch) { case 'b': // Override default programmer baud rate baudrate = str_int(optarg, STR_INT32, &errstr); @@ -960,6 +1014,11 @@ int main(int argc, char *argv[]) { exit(0); break; + case LONGOPT_VERSION: + print_version_message(); + exit(0); + break; + default: pmsg_error("invalid option -%c\n\n", ch); usage();