genversion-B-GONE
authorManuel Nickschas <sputnick@quassel-irc.org>
Sun, 16 Mar 2014 20:42:51 +0000 (21:42 +0100)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sun, 16 Mar 2014 20:42:51 +0000 (21:42 +0100)
Back in the day, we wanted to have information about the git hash a
particular Quassel binary was built from in the About dialog, to allow
for diagnostic purposes. However, we didn't manage to retrieve that
kind of information using CMake alone (we're talking CMake 2.4 here, too);
so we came up with the hack to compile a small binary that would be run
at build time and called the git executable in order to write version
information into a file.

This is not particularly nice, as running random binaries at build time is
frowned upon and can cause problems in some setups, and of course we have
the overhead of building it first.

Meanwhile, we found a nice set of CMake macros created by Ryan Pavlik that
would retrieve that information purely running Git commands, making genversion
obsolete. Together with the configure_file feature of CMake, this allows us
to do this more elegantly.

So gone is genversion, and also the good old trusted version.inc file...

.gitattributes
CMakeLists.txt
cmake/modules/GetGitRevisionDescription.cmake [new file with mode: 0644]
cmake/modules/GetGitRevisionDescription.cmake.in [new file with mode: 0644]
src/CMakeLists.txt
src/common/genversion.cpp [deleted file]
src/common/main.cpp
src/common/quassel.cpp
src/common/quassel.h
version.h.in [new file with mode: 0644]
version.inc [deleted file]

index 3e05b82..d1af528 100644 (file)
@@ -1,2 +1,2 @@
-version.inc    export-subst
+version.h.in           export-subst
 icons/oxygen_quassel   export-ignore
index a220522..8a9303d 100644 (file)
 cmake_minimum_required(VERSION 2.8.9)
 project(QuasselIRC)
 
+# Versions
+set(QUASSEL_MAJOR  0)
+set(QUASSEL_MINOR 11)
+set(QUASSEL_PATCH  0)
+set(QUASSEL_VERSION_STRING "0.11-pre")
+
 include(CheckFunctionExists)
 include(CheckIncludeFile)
 include(CheckCXXCompilerFlag)
@@ -537,20 +543,18 @@ if(NOT WIN32)
   endif(HAVE_UMASK)
 endif(NOT WIN32)
 
-# We need to create a version.gen
-# For this, we create our genversion binary and make sure it is run every time.
-
-setup_qt_variables()
-include_directories(${QUASSEL_QT_INCLUDES})
+# Generate version information from Git
+include(GetGitRevisionDescription)
+get_git_head_revision(GIT_REFSPEC GIT_HEAD)
+git_describe(GIT_DESCRIBE --long)
 
-add_executable(genversion ${CMAKE_SOURCE_DIR}/src/common/genversion.cpp)
-target_link_libraries(genversion ${QUASSEL_QT_LIBRARIES})
-set_target_properties(genversion PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}")
+# Sanitize things if we're not in a Git repo
+if(NOT GIT_HEAD OR NOT GIT_DESCRIBE)
+    set(GIT_HEAD "")
+    set(GIT_DESCRIBE "")
+endif()
 
-get_target_property(GENVERSION_EXECUTABLE genversion LOCATION)
-add_custom_target(genversion_run ALL ${GENVERSION_EXECUTABLE}
-                  ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/src/version.gen)
-add_dependencies(genversion_run genversion)
+configure_file(version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY)
 
 # These variables will be added to the main targets (CORE, QTCLIENT, MONO)
 set(COMMON_DEPS ${RC_WIN32})
diff --git a/cmake/modules/GetGitRevisionDescription.cmake b/cmake/modules/GetGitRevisionDescription.cmake
new file mode 100644 (file)
index 0000000..aa2ef71
--- /dev/null
@@ -0,0 +1,131 @@
+# - Returns a version string from Git
+#
+# These functions force a re-configure on each git commit so that you can
+# trust the values of the variables in your build system.
+#
+#  get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
+#
+# Returns the refspec and sha hash of the current head revision
+#
+#  git_describe(<var> [<additional arguments to git describe> ...])
+#
+# Returns the results of git describe on the source tree, and adjusting
+# the output so that it tests false if an error occurs.
+#
+#  git_get_exact_tag(<var> [<additional arguments to git describe> ...])
+#
+# Returns the results of git describe --exact-match on the source tree,
+# and adjusting the output so that it tests false if there was no exact
+# matching tag.
+#
+# Requires CMake 2.6 or newer (uses the 'function' command)
+#
+# Original Author:
+# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
+# http://academic.cleardefinition.com
+# Iowa State University HCI Graduate Program/VRAC
+#
+# Copyright Iowa State University 2009-2010.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+if(__get_git_revision_description)
+       return()
+endif()
+set(__get_git_revision_description YES)
+
+# We must run the following at "include" time, not at function call time,
+# to find the path to this module rather than the path to a calling list file
+get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
+
+function(get_git_head_revision _refspecvar _hashvar)
+       set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+       set(GIT_DIR "${GIT_PARENT_DIR}/.git")
+       while(NOT EXISTS "${GIT_DIR}")  # .git dir not found, search parent directories
+               set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
+               get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
+               if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
+                       # We have reached the root directory, we are not in git
+                       set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
+                       set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
+                       return()
+               endif()
+               set(GIT_DIR "${GIT_PARENT_DIR}/.git")
+       endwhile()
+       # check if this is a submodule
+       if(NOT IS_DIRECTORY ${GIT_DIR})
+               file(READ ${GIT_DIR} submodule)
+               string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
+               get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
+               get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
+       endif()
+       set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
+       if(NOT EXISTS "${GIT_DATA}")
+               file(MAKE_DIRECTORY "${GIT_DATA}")
+       endif()
+
+       if(NOT EXISTS "${GIT_DIR}/HEAD")
+               return()
+       endif()
+       set(HEAD_FILE "${GIT_DATA}/HEAD")
+       configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
+
+       configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
+               "${GIT_DATA}/grabRef.cmake"
+               @ONLY)
+       include("${GIT_DATA}/grabRef.cmake")
+
+       set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
+       set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
+endfunction()
+
+function(git_describe _var)
+       if(NOT GIT_FOUND)
+               find_package(Git QUIET)
+       endif()
+       get_git_head_revision(refspec hash)
+       if(NOT GIT_FOUND)
+               set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
+               return()
+       endif()
+       if(NOT hash)
+               set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
+               return()
+       endif()
+
+       # TODO sanitize
+       #if((${ARGN}" MATCHES "&&") OR
+       #       (ARGN MATCHES "||") OR
+       #       (ARGN MATCHES "\\;"))
+       #       message("Please report the following error to the project!")
+       #       message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
+       #endif()
+
+       #message(STATUS "Arguments to execute_process: ${ARGN}")
+
+       execute_process(COMMAND
+               "${GIT_EXECUTABLE}"
+               describe
+               ${hash}
+               ${ARGN}
+               WORKING_DIRECTORY
+               "${CMAKE_SOURCE_DIR}"
+               RESULT_VARIABLE
+               res
+               OUTPUT_VARIABLE
+               out
+               ERROR_QUIET
+               OUTPUT_STRIP_TRAILING_WHITESPACE)
+       if(NOT res EQUAL 0)
+                message(STATUS "RES ${res} OUT ${out}")
+               set(out "${out}-${res}-NOTFOUND")
+       endif()
+
+       set(${_var} "${out}" PARENT_SCOPE)
+endfunction()
+
+function(git_get_exact_tag _var)
+       git_describe(out --exact-match ${ARGN})
+       set(${_var} "${out}" PARENT_SCOPE)
+endfunction()
diff --git a/cmake/modules/GetGitRevisionDescription.cmake.in b/cmake/modules/GetGitRevisionDescription.cmake.in
new file mode 100644 (file)
index 0000000..888ce13
--- /dev/null
@@ -0,0 +1,38 @@
+# 
+# Internal file for GetGitRevisionDescription.cmake
+#
+# Requires CMake 2.6 or newer (uses the 'function' command)
+#
+# Original Author:
+# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
+# http://academic.cleardefinition.com
+# Iowa State University HCI Graduate Program/VRAC
+#
+# Copyright Iowa State University 2009-2010.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+set(HEAD_HASH)
+
+file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
+
+string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
+if(HEAD_CONTENTS MATCHES "ref")
+       # named branch
+       string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
+       if(EXISTS "@GIT_DIR@/${HEAD_REF}")
+               configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
+       elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}")
+               configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
+               set(HEAD_HASH "${HEAD_REF}")
+       endif()
+else()
+       # detached HEAD
+       configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
+endif()
+
+if(NOT HEAD_HASH)
+       file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
+       string(STRIP "${HEAD_HASH}" HEAD_HASH)
+endif()
index 75982d1..bc30bbd 100644 (file)
@@ -38,7 +38,7 @@ if(WANT_CORE)
   setup_qt_variables(Network Script Sql ${CORE_QT_MODULES})
   include_directories(${QUASSEL_QT_INCLUDES})
   add_executable(quasselcore common/main.cpp ${COMMON_DEPS} ${CORE_DEPS})
-  add_dependencies(quasselcore po genversion_run)
+  add_dependencies(quasselcore po)
   set_target_properties(quasselcore PROPERTIES
                                     COMPILE_FLAGS "-DBUILD_CORE ${QUASSEL_QT_COMPILEFLAGS}"
                                     OUTPUT_NAME ../quasselcore)
@@ -51,7 +51,7 @@ if(WANT_QTCLIENT)
   setup_qt_variables(Gui Network ${CLIENT_QT_MODULES})
   include_directories(${QUASSEL_QT_INCLUDES})
   add_executable(quasselclient WIN32 common/main.cpp ${COMMON_DEPS} ${CLIENT_DEPS})
-  add_dependencies(quasselclient po genversion_run)
+  add_dependencies(quasselclient po)
   set_target_properties(quasselclient PROPERTIES
                                       COMPILE_FLAGS "-DBUILD_QTUI ${QUASSEL_QT_COMPILEFLAGS} ${CLIENT_COMPILE_FLAGS}"
                                       OUTPUT_NAME ../quasselclient)
@@ -67,7 +67,7 @@ if(WANT_MONO)
     qt4_wrap_cpp(MOC qtui/monoapplication.h)
   endif(NOT WITH_QT5)
   add_executable(quassel WIN32 common/main.cpp qtui/monoapplication.cpp ${MOC} ${COMMON_DEPS} ${CLIENT_DEPS} ${CORE_DEPS})
-  add_dependencies(quassel po genversion_run)
+  add_dependencies(quassel po)
   set_target_properties(quassel PROPERTIES
                                 COMPILE_FLAGS "-DBUILD_MONO ${QUASSEL_QT_COMPILEFLAGS} ${CLIENT_COMPILE_FLAGS}"
                                 OUTPUT_NAME ../quassel)
diff --git a/src/common/genversion.cpp b/src/common/genversion.cpp
deleted file mode 100644 (file)
index 405d391..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2005-2014 by the Quassel Project                        *
- *   devel@quassel-irc.org                                                 *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) version 3.                                           *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
- ***************************************************************************/
-
-/** This is called at compile time and generates a suitable version.gen.
- *  usage: genversion git_root target_file
- */
-
-#include <QDebug>
-#include <QProcess>
-#include <QString>
-#include <QStringList>
-#include <QRegExp>
-#include <QFile>
-#include <QCoreApplication>
-
-int main(int argc, char **argv)
-{
-    if (argc < 3) {
-        qFatal("Usage: ./genversion <git_root> <target_file>");
-        return 255;
-    }
-
-    QCoreApplication app(argc, argv);
-
-    QString gitroot = app.arguments()[1];
-    QString target = app.arguments()[2];
-    QString basever, protover, clientneeds, coreneeds, descrver, dirty;
-    QString committish, commitdate;
-
-    // check Git for information if present
-    if (QFile::exists(gitroot + "/.git")) {
-        // try to execute git-describe to get a version string
-        QProcess git;
-        git.setWorkingDirectory(gitroot);
-    #ifdef Q_OS_WIN
-        git.start("cmd.exe", QStringList() << "/C" << "git" << "describe" << "--long");
-    #else
-        git.start("git", QStringList() << "describe" << "--long");
-    #endif
-        if (git.waitForFinished(10000)) {
-            QString descr = git.readAllStandardOutput().trimmed();
-            if (!descr.isEmpty() && !descr.contains("fatal")) {
-                // seems we have a valid git describe string
-                descrver = descr;
-                // check if the workdir is dirty
-        #ifdef Q_OS_WIN
-                git.start("cmd.exe", QStringList() << "/C" << "git" << "diff-index" << "--name-only" << "HEAD");
-        #else
-                git.start("git", QStringList() << "diff-index" << "--name-only" << "HEAD");
-        #endif
-                if (git.waitForFinished(10000)) {
-                    if (!git.readAllStandardOutput().isEmpty()) dirty = "*";
-                }
-                // get a full committish
-        #ifdef Q_OS_WIN
-                git.start("cmd.exe", QStringList() << "/C" << "git" << "rev-parse" << "HEAD");
-        #else
-                git.start("git", QStringList() << "rev-parse" << "HEAD");
-        #endif
-                if (git.waitForFinished(10000)) {
-                    committish = git.readAllStandardOutput().trimmed();
-                }
-                // Now we do some replacement magic...
-                //QRegExp rxCheckTag("(.*)-0-g[0-9a-f]+\n$");
-                //QRegExp rxGittify("(.*)-(\\d+)-g([0-9a-f]+)\n$");
-                //gitversion.replace(rxCheckTag, QString("\\1%1").arg(dirty));
-                //gitversion.replace(rxGittify, QString("\\1:git-\\3+\\2%1").arg(dirty));
-            }
-        }
-    }
-
-    // parse version.inc
-    QFile verfile(gitroot + "/version.inc");
-    if (verfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
-        QString ver = verfile.readAll();
-
-        QRegExp rxBasever("baseVersion\\s*=\\s*\"(.*)\";");
-        if (rxBasever.indexIn(ver) >= 0)
-            basever = rxBasever.cap(1);
-
-        QRegExp rxProtover("protocolVersion\\s*=\\s*(\\d+)");
-        if (rxProtover.indexIn(ver) >= 0)
-            protover = rxProtover.cap(1);
-
-        QRegExp rxClientneeds("clientNeedsProtocol\\s*=\\s*(\\d+)");
-        if (rxClientneeds.indexIn(ver) >= 0)
-            clientneeds = rxClientneeds.cap(1);
-
-        QRegExp rxCoreneeds("coreNeedsProtocol\\s*=\\s*(\\d+)");
-        if (rxCoreneeds.indexIn(ver) >= 0)
-            coreneeds = rxCoreneeds.cap(1);
-
-        if (committish.isEmpty()) {
-            QRegExp rxCommit("distCommittish\\s*=\\s*([0-9a-f]+)");
-            if (rxCommit.indexIn(ver) >= 0) committish = rxCommit.cap(1);
-        }
-
-        QRegExp rxTimestamp("distCommitDate\\s*=\\s*([0-9]+)");
-        if (rxTimestamp.indexIn(ver) >= 0) commitdate = rxTimestamp.cap(1);
-        verfile.close();
-    }
-
-    // generate the contents for version.gen
-    QByteArray contents = QString("QString buildinfo = \"%1,%2,%3,%4,%5,%6,%7,%8\";\n")
-                          .arg(basever, descrver, dirty, committish, commitdate, protover, clientneeds, coreneeds)
-                          .toAscii();
-
-    QFile gen(target);
-    if (!gen.open(QIODevice::ReadWrite | QIODevice::Text)) {
-        qFatal("%s", qPrintable(QString("Could not write %1!").arg(target)));
-        return EXIT_FAILURE;
-    }
-    QByteArray oldContents = gen.readAll();
-    if (oldContents != contents) { // only touch the file if something changed
-        gen.seek(0);
-        gen.resize(0);
-        gen.write(contents);
-        gen.waitForBytesWritten(10000);
-    }
-    gen.close();
-
-    return EXIT_SUCCESS;
-}
index 2036194..149167c 100644 (file)
@@ -52,10 +52,7 @@ Q_IMPORT_PLUGIN(qgif)
 
 int main(int argc, char **argv)
 {
-    // Setup build information and version string
-  # include "version.gen"
-    buildinfo.append(QString(",%1,%2").arg(__DATE__, __TIME__));
-    Quassel::setupBuildInfo(buildinfo);
+    Quassel::setupBuildInfo();
     QCoreApplication::setApplicationName(Quassel::buildInfo().applicationName);
     QCoreApplication::setOrganizationName(Quassel::buildInfo().organizationName);
     QCoreApplication::setOrganizationDomain(Quassel::buildInfo().organizationDomain);
index 23202a7..6490eb9 100644 (file)
@@ -46,6 +46,8 @@
 #include "syncableobject.h"
 #include "types.h"
 
+#include "../../version.h"
+
 Quassel::BuildInfo Quassel::_buildInfo;
 AbstractCliParser *Quassel::_cliParser = 0;
 Quassel::RunMode Quassel::_runMode;
@@ -209,7 +211,7 @@ void Quassel::registerMetaTypes()
 }
 
 
-void Quassel::setupBuildInfo(const QString &generated)
+void Quassel::setupBuildInfo()
 {
     _buildInfo.applicationName = "Quassel IRC";
     _buildInfo.coreApplicationName = "quasselcore";
@@ -217,17 +219,22 @@ void Quassel::setupBuildInfo(const QString &generated)
     _buildInfo.organizationName = "Quassel Project";
     _buildInfo.organizationDomain = "quassel-irc.org";
 
-    QStringList gen = generated.split(',');
-    Q_ASSERT(gen.count() == 10);
-    _buildInfo.baseVersion = gen[0];
-    _buildInfo.generatedVersion = gen[1];
-    _buildInfo.isSourceDirty = !gen[2].isEmpty();
-    _buildInfo.commitHash = gen[3];
-    _buildInfo.commitDate = gen[4].toUInt();
-    _buildInfo.protocolVersion = gen[5].toUInt();
-    _buildInfo.clientNeedsProtocol = gen[6].toUInt();
-    _buildInfo.coreNeedsProtocol = gen[7].toUInt();
-    _buildInfo.buildDate = QString("%1 %2").arg(gen[8], gen[9]);
+    _buildInfo.protocolVersion = 10; // FIXME: deprecated, will be removed
+
+    _buildInfo.baseVersion = QUASSEL_VERSION_STRING;
+    _buildInfo.generatedVersion = GIT_DESCRIBE;
+
+    // This will be imprecise for incremental builds not touching this file, but we really don't want to always recompile
+    _buildInfo.buildDate = QString("%1 %2").arg(__DATE__, __TIME__);
+
+    // Check if we got a commit hash
+    if (!QString(GIT_HEAD).isEmpty())
+        _buildInfo.commitHash = GIT_HEAD;
+    else if (!QString(DIST_HASH).contains("Format")) {
+        _buildInfo.commitHash = DIST_HASH;
+        _buildInfo.commitDate = QString(DIST_DATE).toUInt();
+    }
+
     // create a nice version string
     if (_buildInfo.generatedVersion.isEmpty()) {
         if (!_buildInfo.commitHash.isEmpty()) {
@@ -242,26 +249,23 @@ void Quassel::setupBuildInfo(const QString &generated)
         }
         else {
             // we only have a base version :(
-            _buildInfo.plainVersionString = QString("v%1 (unknown rev)").arg(_buildInfo.baseVersion);
+            _buildInfo.plainVersionString = QString("v%1 (unknown revision)").arg(_buildInfo.baseVersion);
         }
     }
     else {
         // analyze what we got from git-describe
-        QRegExp rx("(.*)-(\\d+)-g([0-9a-f]+)$");
+        QRegExp rx("(.*)-(\\d+)-g([0-9a-f]+)(-dirty)?$");
         if (rx.exactMatch(_buildInfo.generatedVersion)) {
             QString distance = rx.cap(2) == "0" ? QString() : QString("%1+%2 ").arg(rx.cap(1), rx.cap(2));
             _buildInfo.plainVersionString = QString("v%1 (%2git-%3%4)")
-                                            .arg(_buildInfo.baseVersion, distance, rx.cap(3))
-                                            .arg(_buildInfo.isSourceDirty ? "*" : "");
+                                            .arg(_buildInfo.baseVersion, distance, rx.cap(3), rx.cap(4));
             if (!_buildInfo.commitHash.isEmpty()) {
                 _buildInfo.fancyVersionString = QString("v%1 (%2git-<a href=\"http://git.quassel-irc.org/?p=quassel.git;a=commit;h=%5\">%3</a>%4)")
-                                                .arg(_buildInfo.baseVersion, distance, rx.cap(3))
-                                                .arg(_buildInfo.isSourceDirty ? "*" : "")
-                                                .arg(_buildInfo.commitHash);
+                                                .arg(_buildInfo.baseVersion, distance, rx.cap(3), rx.cap(4), _buildInfo.commitHash);
             }
         }
         else {
-            _buildInfo.plainVersionString = QString("v%1 (invalid rev)").arg(_buildInfo.baseVersion);
+            _buildInfo.plainVersionString = QString("v%1 (invalid revision)").arg(_buildInfo.baseVersion);
         }
     }
     if (_buildInfo.fancyVersionString.isEmpty())
index b6fc378..b141f32 100644 (file)
@@ -49,10 +49,8 @@ public:
         QString commitHash;
         uint commitDate;
         QString buildDate;
-        bool isSourceDirty;
-        uint protocolVersion;
-        uint clientNeedsProtocol;
-        uint coreNeedsProtocol;
+
+        uint protocolVersion; // deprecated
 
         QString applicationName;
         QString coreApplicationName;
@@ -85,7 +83,7 @@ public:
 
     virtual ~Quassel();
 
-    static void setupBuildInfo(const QString &generated);
+    static void setupBuildInfo();
     static inline const BuildInfo &buildInfo();
     static inline RunMode runMode();
 
diff --git a/version.h.in b/version.h.in
new file mode 100644 (file)
index 0000000..2cd1232
--- /dev/null
@@ -0,0 +1,13 @@
+// Version information
+#define QUASSEL_MAJOR @QUASSEL_MAJOR@
+#define QUASSEL_MINOR @QUASSEL_MINOR@
+#define QUASSEL_PATCH @QUASSEL_PATCH@
+#define QUASSEL_VERSION_STRING "@QUASSEL_VERSION_STRING@"
+
+// Determined from Git
+#define GIT_HEAD "@GIT_HEAD@"
+#define GIT_DESCRIBE "@GIT_DESCRIBE@"
+
+// Will be substituted in official tarballs
+#define DIST_HASH "$Format:%H$"
+#define DIST_DATE "$Format:%at$"
diff --git a/version.inc b/version.inc
deleted file mode 100644 (file)
index 1f13e4c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-//! This is the fallback version number in case we can't autogenerate one
-baseVersion = "0.11-pre";
-
-protocolVersion = 10;       //< Version of the client/core protocol
-coreNeedsProtocol   = 10;   //< Minimum protocol version the core needs
-clientNeedsProtocol = 10;   //< Minimum protocol version the client needs
-
-distCommittish = $Format:%H$
-distCommitDate = $Format:%at$