Introduce version.c to limit recompilation on version changes.
authorAndre Noll <maan@systemlinux.org>
Fri, 12 Apr 2013 12:23:45 +0000 (14:23 +0200)
committerAndre Noll <maan@systemlinux.org>
Thu, 13 Jun 2013 16:29:03 +0000 (18:29 +0200)
Currently version.h includes git-version.h which changes whenever
a different commit is checked out or the working tree becomes dirty
because a file has been modified. Consequently, all .c files that
include this header must be recompiled in this case.

To limit the number of recompilations, this commit introduces
version.c, which contains functions that return the various types of
the version string. It is now the only file that includes version.h,
so only version.o must be rebuilt if git-version.h changes.

This also adds the build date, OS and CC version to the version output.

17 files changed:
afh.c
audioc.c
audiod.c
client.c
client_common.c
command.c
configure.ac
error.h
fade.c
filter.c
gui.c
play.c
recv.c
server.c
version.c [new file with mode: 0644]
version.h
write.c

diff --git a/afh.c b/afh.c
index 699a6d8..f02b47b 100644 (file)
--- a/afh.c
+++ b/afh.c
@@ -73,7 +73,7 @@ int main(int argc, char **argv)
 
        afh_cmdline_parser(argc, argv, &conf);
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
-       HANDLE_VERSION_FLAG("afh", conf);
+       version_handle_flag("afh", conf.version_given);
        ret = -E_AFH_SYNTAX;
        if (conf.inputs_num == 0)
                goto out;
index 6a88671..0147b4c 100644 (file)
--- a/audioc.c
+++ b/audioc.c
@@ -194,7 +194,7 @@ __noreturn static void interactive_session(void)
                .loglevel = loglevel,
                .completers = audiod_completers,
        };
-       PARA_NOTICE_LOG("\n%s\n", VERSION_TEXT("audioc"));
+       PARA_NOTICE_LOG("\n%s\n", version_text("audioc"));
        if (conf.history_file_given)
                history_file = para_strdup(conf.history_file_arg);
        else {
@@ -286,8 +286,8 @@ int main(int argc, char *argv[])
        size_t bufsize;
 
        audioc_cmdline_parser(argc, argv, &conf);
-       HANDLE_VERSION_FLAG("audioc", conf);
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
+       version_handle_flag("audioc", conf.version_given);
        cf = configfile_exists();
        if (cf) {
                struct audioc_cmdline_parser_params params = {
index e0ca15e..c183491 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -1305,7 +1305,7 @@ __noreturn static void print_help_and_die(void)
        const char **p = d? audiod_args_info_detailed_help
                : audiod_args_info_help;
 
-       printf_or_die("%s\n\n", VERSION_SINGLE_LINE("audiod"));
+       printf_or_die("%s\n\n", version_single_line("audiod"));
        printf_or_die("%s\n\n", audiod_args_info_usage);
        for (; *p; p++)
                printf_or_die("%s\n", *p);
@@ -1351,8 +1351,8 @@ int main(int argc, char *argv[])
 
        valid_fd_012();
        audiod_cmdline_parser_ext(argc, argv, &conf, &params);
-       HANDLE_VERSION_FLAG("audiod", conf);
        daemon_set_loglevel(conf.loglevel_arg);
+       version_handle_flag("audiod", conf.version_given);
        /* init receivers/filters/writers early to make help work */
        recv_init();
        filter_init();
index 90dc432..3587a97 100644 (file)
--- a/client.c
+++ b/client.c
@@ -477,7 +477,7 @@ __noreturn static void interactive_session(void)
                .completers = completers,
        };
 
-       PARA_NOTICE_LOG("\n%s\n", VERSION_TEXT("client"));
+       PARA_NOTICE_LOG("\n%s\n", version_text("client"));
        if (ct->conf.history_file_given)
                history_file = para_strdup(ct->conf.history_file_arg);
        else {
index f4b09cd..754b5bf 100644 (file)
@@ -641,7 +641,7 @@ int client_parse_config(int argc, char *argv[], struct client_task **ct_ptr,
        ret = -E_CLIENT_SYNTAX;
        if (client_cmdline_parser(argc, argv, &ct->conf))
                goto out;
-       HANDLE_VERSION_FLAG("client", ct->conf);
+       version_handle_flag("client", ct->conf.version_given);
 
        ct->config_file = ct->conf.config_file_given?
                para_strdup(ct->conf.config_file_arg) :
index ec822c8..79ca365 100644 (file)
--- a/command.c
+++ b/command.c
@@ -395,7 +395,8 @@ static int com_si(struct command_context *cc)
                free(info);
        }
        ut = get_server_uptime_str(now);
-       ret = xasprintf(&msg, "version: " GIT_VERSION "\n"
+       ret = xasprintf(&msg,
+               "version: %s\n"
                "up: %s\nplayed: %u\n"
                "server_pid: %d\n"
                "afs_pid: %d\n"
@@ -403,6 +404,7 @@ static int com_si(struct command_context *cc)
                "current loglevel: %s\n"
                "supported audio formats: %s\n"
                "%s",
+               version_git(),
                ut, mmd->num_played,
                (int)getppid(),
                (int)mmd->afs_pid,
@@ -431,11 +433,9 @@ static int com_version(struct command_context *cc)
 
        if (cc->argc != 1)
                return -E_COMMAND_SYNTAX;
-       msg = VERSION_TEXT("server") "built: " BUILD_DATE "\n" UNAME_RS
-               ", " CC_VERSION "\n";
-       len = strlen(msg);
+       len = xasprintf(&msg, "%s", version_text("server"));
        if (cc->use_sideband)
-               return send_sb(&cc->scc, msg, len, SBD_OUTPUT, true);
+               return send_sb(&cc->scc, msg, len, SBD_OUTPUT, false);
        return sc_send_bin_buffer(&cc->scc, msg, len);
 }
 
index 12959c8..47dc6ac 100644 (file)
@@ -102,7 +102,7 @@ all_errlist_objs="mp3_afh afh_common net string signal time daemon
        exec send_common ggo udp_recv color fec fecdec_filter
        prebuffer_filter bitstream imdct check_wav
        wma_afh wma_common wmadec_filter buffer_tree crypt_common
-       gui gui_theme sideband afh_recv play"
+       gui gui_theme sideband afh_recv play version"
 
 executables="recv filter audioc write client afh audiod play"
 
@@ -111,49 +111,50 @@ recv_cmdline_objs="add_cmdline(recv http_recv dccp_recv udp_recv afh_recv)"
 recv_errlist_objs="
        http_recv recv_common recv time string net dccp_recv fd
        sched stdout ggo udp_recv buffer_tree afh_recv afh_common
-       wma_afh wma_common mp3_afh
+       wma_afh wma_common mp3_afh version
 "
 
 recv_ldflags=""
 
 filter_cmdline_objs="add_cmdline(filter compress_filter amp_filter prebuffer_filter)"
 filter_errlist_objs="filter_common wav_filter compress_filter filter string
-       stdin stdout sched fd amp_filter ggo fecdec_filter fec
+       stdin stdout sched fd amp_filter ggo fecdec_filter fec version
        prebuffer_filter time bitstream imdct wma_common wmadec_filter buffer_tree"
 filter_ldflags="-lm"
 filters=" compress wav amp fecdec wmadec prebuffer"
 
 audioc_cmdline_objs="add_cmdline(audioc)"
-audioc_errlist_objs="audioc string net fd"
+audioc_errlist_objs="audioc string net fd version"
 audioc_ldflags=""
 
 audiod_cmdline_objs="add_cmdline(audiod compress_filter http_recv dccp_recv file_write client amp_filter udp_recv prebuffer_filter)"
 audiod_errlist_objs="audiod signal string daemon stat net crypt_common sideband
        time grab_client filter_common wav_filter compress_filter amp_filter http_recv dccp_recv
        recv_common fd sched write_common file_write audiod_command fecdec_filter
-       client_common ggo udp_recv color fec prebuffer_filter
+       client_common ggo udp_recv color fec prebuffer_filter version
        bitstream imdct wma_common wmadec_filter buffer_tree"
 audiod_ldflags="-lm"
 audiod_audio_formats="wma"
 
 afh_cmdline_objs="add_cmdline(afh)"
-afh_errlist_objs="afh string fd mp3_afh afh_common time wma_afh wma_common"
+afh_errlist_objs="afh string fd mp3_afh afh_common time wma_afh wma_common
+       version"
 afh_ldflags=""
 
 write_cmdline_objs="add_cmdline(write file_write)"
 write_errlist_objs="write write_common file_write time fd string sched stdin
-       buffer_tree ggo check_wav"
+       buffer_tree ggo check_wav version"
 write_ldflags=""
 writers=" file"
 default_writer="FILE_WRITE"
 
 client_cmdline_objs="add_cmdline(client)"
 client_errlist_objs="client net string fd sched stdin stdout time sideband
-       client_common buffer_tree crypt_common"
+       client_common buffer_tree crypt_common version"
 client_ldflags=""
 
 gui_cmdline_objs="add_cmdline(gui)"
-gui_errlist_objs="exec signal string stat ringbuffer fd gui gui_theme time"
+gui_errlist_objs="exec signal string stat ringbuffer fd gui gui_theme version time"
 gui_objs="$gui_cmdline_objs $gui_errlist_objs"
 play_errlist_objs="play fd sched ggo buffer_tree time string net
        afh_recv afh_common
@@ -163,6 +164,7 @@ play_errlist_objs="play fd sched ggo buffer_tree time string net
        wav_filter compress_filter amp_filter prebuffer_filter fecdec_filter
                wmadec_filter
        write_common file_write
+       version
 "
 play_cmdline_objs="add_cmdline(http_recv dccp_recv udp_recv afh_recv compress_filter amp_filter prebuffer_filter file_write play)"
 play_ldflags="-lm"
@@ -294,7 +296,8 @@ else
                string signal time daemon http_send close_on_fork mm
                crypt_common ipc dccp_send fd user_list chunk_queue
                afs aft mood score attribute blob playlist sched acl
-               send_common udp_send color fec wma_afh wma_common sideband"
+               send_common udp_send color fec wma_afh wma_common sideband
+               version"
        all_errlist_objs="$all_errlist_objs server vss command
                http_send close_on_fork mm ipc dccp_send user_list
                chunk_queue afs aft mood score attribute blob playlist
@@ -878,7 +881,7 @@ AC_CHECK_HEADER(sys/soundcard.h, [
 
        write_errlist_objs="$write_errlist_objs oss_write"
        write_cmdline_objs="$write_cmdline_objs add_cmdline(oss_write)"
-       fade_errlist_objs="$fade_errlist_objs oss_mix"
+       fade_errlist_objs="$fade_errlist_objs oss_mix version"
        all_errlist_objs="$all_errlist_objs oss_write oss_mix"
 
        writers="$writers oss"
diff --git a/error.h b/error.h
index ca172cb..41a7fe1 100644 (file)
--- a/error.h
+++ b/error.h
@@ -34,6 +34,7 @@ DEFINE_ERRLIST_OBJECT_ENUM;
 #define STDIN_ERRORS
 #define WRITE_ERRORS
 #define CHECK_WAV_ERRORS
+#define VERSION_ERRORS
 
 extern const char **para_errlist[];
 
diff --git a/fade.c b/fade.c
index e6f550a..76d6a8b 100644 (file)
--- a/fade.c
+++ b/fade.c
@@ -293,8 +293,8 @@ int main(int argc, char *argv[])
        struct mixer_handle *h = NULL;
 
        fade_cmdline_parser(argc, argv, &conf);
-       HANDLE_VERSION_FLAG("fade", conf);
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
+       version_handle_flag("fade", conf.version_given);
        ret = configfile_exists();
        if (!ret && conf.config_file_given) {
                PARA_EMERG_LOG("can not read config file %s\n",
index 65d6c64..9ece063 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -51,7 +51,7 @@ __noreturn static void print_help_and_die(void)
        const char **p = d? filter_args_info_detailed_help
                : filter_args_info_help;
 
-       printf_or_die("%s\n\n", VERSION_SINGLE_LINE("filter"));
+       printf_or_die("%s\n\n", version_single_line("filter"));
        printf_or_die("%s\n\n", filter_args_info_usage);
        for (; *p; p++)
                printf_or_die("%s\n", *p);
@@ -64,7 +64,7 @@ static int parse_config(void)
        static char *cf; /* config file */
        struct stat statbuf;
 
-       HANDLE_VERSION_FLAG("filter", conf);
+       version_handle_flag("filter", conf.version_given);
        if (conf.help_given || conf.detailed_help_given)
                print_help_and_die();
        if (!cf) {
diff --git a/gui.c b/gui.c
index 5092315..4e293fe 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -1520,8 +1520,8 @@ int main(int argc, char *argv[])
        _argv = argv;
 
        gui_cmdline_parser(argc, argv, &conf); /* exits on errors */
-       HANDLE_VERSION_FLAG("gui", conf);
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
+       version_handle_flag("gui", conf.version_given);
        cf = configfile_exists();
        if (!cf && conf.config_file_given) {
                fprintf(stderr, "can not read config file %s\n",
diff --git a/play.c b/play.c
index 9204792..255886b 100644 (file)
--- a/play.c
+++ b/play.c
@@ -153,7 +153,7 @@ __noreturn static void print_help_and_die(void)
        const char **p = d? play_args_info_detailed_help
                : play_args_info_help;
 
-       printf_or_die("%s\n\n", VERSION_SINGLE_LINE("play"));
+       printf_or_die("%s\n\n", version_single_line("play"));
        printf_or_die("%s\n\n", play_args_info_usage);
        if (d)
                printf_or_die("%s\n", PP_DESC);
@@ -175,8 +175,8 @@ static void parse_config_or_die(int argc, char *argv[])
        };
 
        play_cmdline_parser_ext(argc, argv, &conf, &params);
-       HANDLE_VERSION_FLAG("play", conf);
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
+       version_handle_flag("play", conf.version_given);
        if (conf.help_given || conf.detailed_help_given)
                print_help_and_die();
        if (conf.config_file_given)
@@ -1042,7 +1042,7 @@ static void session_open(__a_unused struct play_task *pt)
        char *history_file;
        struct sigaction act;
 
-       PARA_NOTICE_LOG("\n%s\n", VERSION_TEXT("play"));
+       PARA_NOTICE_LOG("\n%s\n", version_text("play"));
        if (conf.history_file_given)
                history_file = para_strdup(conf.history_file_arg);
        else {
diff --git a/recv.c b/recv.c
index f8b5847..a3fdd30 100644 (file)
--- a/recv.c
+++ b/recv.c
@@ -43,7 +43,7 @@ __noreturn static void print_help_and_die(void)
        const char **p = d? recv_args_info_detailed_help
                : recv_args_info_help;
 
-       printf_or_die("%s\n\n", VERSION_SINGLE_LINE("recv"));
+       printf_or_die("%s\n\n", version_single_line("recv"));
        printf_or_die("%s\n\n", recv_args_info_usage);
        for (; *p; p++)
                printf_or_die("%s\n", *p);
@@ -72,7 +72,7 @@ int main(int argc, char *argv[])
 
        recv_cmdline_parser(argc, argv, &conf);
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
-       HANDLE_VERSION_FLAG("recv", conf);
+       version_handle_flag("recv", conf.version_given);
        recv_init();
        if (conf.help_given || conf.detailed_help_given)
                print_help_and_die();
index 31d29c7..cd985c6 100644 (file)
--- a/server.c
+++ b/server.c
@@ -488,9 +488,9 @@ static void server_init(int argc, char **argv)
        init_random_seed_or_die();
        /* parse command line options */
        server_cmdline_parser_ext(argc, argv, &conf, &params);
-       HANDLE_VERSION_FLAG("server", conf);
-       drop_privileges_or_die(conf.user_arg, conf.group_arg);
        daemon_set_loglevel(conf.loglevel_arg);
+       version_handle_flag("server", conf.version_given);
+       drop_privileges_or_die(conf.user_arg, conf.group_arg);
        /* parse config file, open log and set defaults */
        parse_config_or_die(0);
        log_welcome("para_server");
diff --git a/version.c b/version.c
new file mode 100644 (file)
index 0000000..d2df481
--- /dev/null
+++ b/version.c
@@ -0,0 +1,76 @@
+#include "para.h"
+
+/** \file version.h Macros for printing the version string. */
+
+#include "git-version.h"
+
+/**
+ * Get the raw git version string
+ *
+ * \return The string generated by the GIT-VERSION-GEN script. It is passed
+ * as a preprocessor define during compilation.
+ */
+const char *version_git(void)
+{
+       return GIT_VERSION;
+}
+
+/**
+ * Get the version string for an executable.
+ *
+ * \param pfx The program name (without the leading "para_").
+ *
+ * \return A statically allocated string which contains the program name, the
+ * git version and the codename. It must not be freed by the caller.
+ */
+const char *version_single_line(const char *pfx)
+{
+       static char buf[100];
+       snprintf(buf, sizeof(buf) - 1,
+               "para_%s " GIT_VERSION " (" CODENAME ")", pfx);
+       return buf;
+}
+
+/**
+ * Get the full version text.
+ *
+ * \param pfx See \ref version_single_line().
+ *
+ * \return A string containing the same text as returned by \ref
+ * version_single_line(), augmented by additional build information, a
+ * copyright text and the email address of the author.
+ *
+ * Like \ref version_single_line(), this string is stored in a statically
+ * allocated buffer and must not be freed.
+ */
+const char *version_text(const char *pfx)
+{
+       static char buf[512];
+
+       snprintf(buf, sizeof(buf) - 1, "%s\n"
+               "built: " BUILD_DATE ", " UNAME_RS ", " CC_VERSION "\n"
+               "Copyright (C) 2013 Andre Noll\n"
+               "This is free software with ABSOLUTELY NO WARRANTY."
+               " See COPYING for details.\n"
+               "Report bugs to <maan@systemlinux.org>.\n",
+               version_single_line(pfx)
+       );
+       return buf;
+}
+
+/**
+ * Print the version text and exit successfully.
+ *
+ * \param pfx See \ref version_single_line().
+ * \param flag Whether --version was given.
+ *
+ * If \a flag is false, this function does nothing. Otherwise it prints the
+ * full version text as returned by \ref version_text() and exits successfully.
+ */
+void version_handle_flag(const char *pfx, bool flag)
+{
+       if (!flag)
+               return;
+       printf("%s", version_text(pfx));
+       exit(EXIT_SUCCESS);
+}
index 6309fd0..3dd5ba2 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1,21 +1,6 @@
-/** \file version.h Macros for printing the version string. */
-
-#include "git-version.h"
-
-#define VERSION_SINGLE_LINE(prefix) "para_" prefix \
-       " " GIT_VERSION " (" CODENAME ")"
-
-/** Version text printed by all executables if -V was given. */
-#define VERSION_TEXT(prefix) VERSION_SINGLE_LINE(prefix) "\n" \
-       "Copyright (C) 2013 Andre Noll\n" \
-       "This is free software with ABSOLUTELY NO WARRANTY." \
-       " See COPYING for details.\n" \
-       "Report bugs to <maan@systemlinux.org>.\n"
-
-/** Print out \p VERSION_TEXT and exit if version flag was given. */
-#define HANDLE_VERSION_FLAG(_prefix, _args_info_struct) \
-       if (_args_info_struct.version_given) { \
-               printf("%s", VERSION_TEXT(_prefix)); \
-               exit(EXIT_SUCCESS); \
-       }
+/** \file version.h Functions for printing the version string. */
 
+const char *version_git(void);
+const char *version_single_line(const char *pfx);
+const char *version_text(const char *pfx);
+void version_handle_flag(const char *pfx, bool flag);
diff --git a/write.c b/write.c
index 0f04fe5..73cddf8 100644 (file)
--- a/write.c
+++ b/write.c
@@ -39,7 +39,7 @@ __noreturn static void print_help_and_die(void)
        const char **p = d? write_args_info_detailed_help
                : write_args_info_help;
 
-       printf_or_die("%s\n\n", VERSION_SINGLE_LINE("write"));
+       printf_or_die("%s\n\n", version_single_line("write"));
        printf_or_die("%s\n\n", write_args_info_usage);
        for (; *p; p++)
                printf_or_die("%s\n", *p);
@@ -174,7 +174,7 @@ int main(int argc, char *argv[])
        write_cmdline_parser(argc, argv, &conf);
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
        writer_init();
-       HANDLE_VERSION_FLAG("write", conf);
+       version_handle_flag("write", conf.version_given);
        if (conf.help_given || conf.detailed_help_given)
                print_help_and_die();