From: Manuel Nickschas Date: Sun, 15 Jun 2008 00:39:17 +0000 (+0200) Subject: Merge branch 'cmake' X-Git-Tag: 0.3.0~381^2~2 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=cb1918d94b5d8ec9f05a192c96fab938782dabf5;hp=2dc003e929312add334ccb4d48b453d942d89b7b Merge branch 'cmake' --- diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..bc148063 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,190 @@ +# This is the cmake-based build system for Quassel IRC. +# You may pass various options to cmake: +# -DBUILD= : Select binaries to build. may contain any combination +# of "core", "client", "mono" or "all". +# -DQT=/path/to/qt : Choose a Qt4 installation to use instead of the system Qt4 +# -DSTATIC=1 : Enable static building of Quassel, most useful with a static Qt. +# -DSTATICWIN=1 : Enable static building for Windows. +# -DSPUTDEV : Do not use. +# +# NOTE: You need to remove CMakeCache.txt if you plan to change any of these values! + +project(QuasselIRC) + +cmake_minimum_required(VERSION 2.4.5) + +# This would suppress annoying warnings on cmake-2.6, but we can't use it +# with 2.4, so... DUH! +# cmake_policy(SET CMP0003 OLD) # suppress linker warnings + +if(STATICWIN) + set(CMAKE_BUILD_TYPE Release) +endif(STATICWIN) + +# Enable various flags on gcc +include(CheckCXXCompilerFlag) +check_cxx_compiler_flag(-Wall Wall) +if(Wall) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") +endif(Wall) +check_cxx_compiler_flag(-Wextra Wextra) +if(Wextra) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra") +endif(Wextra) +check_cxx_compiler_flag(-ansi ansi) +if(ansi) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ansi") +endif(ansi) + +set(QT_MIN_VERSION "4.4.0") + +# By default, we build all binaries +if(NOT DEFINED BUILD) + set(BUILD all) +endif(NOT DEFINED BUILD) + +# User might define which binaries to build by invoking cmake -DBUILD=, +# where might contain any combination of "core", "client", "mono" or "all" +if(BUILD MATCHES all) + set(BUILD_CORE true) + set(BUILD_QTCLIENT true) + set(BUILD_MONO true) + message(STATUS "Building Quassel Client, Quassel Core and monolithic Quassel.") +else(BUILD MATCHES all) + if(BUILD MATCHES core) + set(BUILD_CORE true) + message(STATUS "Building Quassel Core") + endif(BUILD MATCHES core) + if(BUILD MATCHES client) + set(BUILD_QTCLIENT true) + message(STATUS "Building Quassel Client") + endif(BUILD MATCHES client) + if(BUILD MATCHES mono) + set(BUILD_MONO true) + message(STATUS "Building monolithic Quassel") + endif(BUILD MATCHES mono) +endif(BUILD MATCHES all) + +# Enable mostly b0rked stuff (new ChatView), do not enable this unless you know what you do... +if(SPUTDEV) + add_definitions(-DSPUTDEV) +endif(SPUTDEV) + +# Set up OpenSSL +find_package(OpenSSL) + +# Select a Qt installation here, if you don't want to use system Qt +if(DEFINED QT) + # FindQt4 will look for the qmake binary in $PATH, so we just prepend the Qt dir + set(ENV{PATH} ${QT}/bin:$ENV{PATH}) + #SET(QT_QMAKE_EXECUTABLE ${QT}/bin/qmake CACHE FILEPATH "" FORCE) +endif(DEFINED QT) + +# Now that we have the correct $PATH, lets find Qt! +find_package(Qt4 REQUIRED) + +set(QT_DONT_USE_QTGUI 1) +include(${QT_USE_FILE}) +include_directories(${QT_INCLUDES}) + +# We need to create a version.gen +# For this, we create our genversion binary and make sure it is run every time. +add_executable(genversion ${CMAKE_SOURCE_DIR}/src/common/genversion.cpp) +target_link_libraries(genversion ${QT_LIBRARIES}) + +add_custom_target(genversion_run ALL ${CMAKE_BINARY_DIR}/genversion + ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/src/common/version.gen) +add_dependencies(genversion_run genversion) + +# Add needed subdirs +add_subdirectory(src/common) +include_directories(src/common) +if(BUILD_CORE OR BUILD_MONO) + add_subdirectory(src/core) + include_directories(src/core) +endif(BUILD_CORE OR BUILD_MONO) +if(BUILD_QTCLIENT OR BUILD_MONO) + add_subdirectory(src/client) + add_subdirectory(src/uisupport) + add_subdirectory(src/qtui) + include_directories(src/client) + include_directories(src/uisupport) + include_directories(src/qtui) +endif(BUILD_QTCLIENT OR BUILD_MONO) + +# Make sure version.gen exists before building mod_common +add_dependencies(mod_common genversion_run) + +# Add resources +qt4_add_resources(RC_I18N i18n/i18n.qrc) +qt4_add_resources(RC_ICONS src/icons/icons.qrc) +qt4_add_resources(RC_QUASSEL_ICONS src/icons/quassel-icons.qrc) +qt4_add_resources(RC_SQL src/core/sql.qrc) + +# Set global buildflags +if(DEFINED STATIC) + set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc ${CMAKE_EXE_LINKER_FLAGS}") + link_directories(${CMAKE_BINARY_DIR}/staticlibs) +endif(DEFINED STATIC) + +if(STATICWIN AND WIN32) + link_libraries(imm32 winmm) # missing by default :/ + if(OPENSSL_FOUND) + link_libraries(${OPENSSL_LIBRARIES} libeay32MD) + endif(OPENSSL_FOUND) +endif(STATICWIN AND WIN32) + +if(WIN32) + set(WIN32_RC src/icons/win32.rc) # for app icons on windows +endif(WIN32) + +# Here comes the dirty part. Our targets need different Qt4 modules, i.e. different libs +# and defines. We can't simply include UseQt4 several times, since definitions add up. +# We workaround this by using our own macro to figure out what to add. + +# This macro sets variables for additional Qt modules. +macro(setup_qt4_variables) + set(QUASSEL_QT_LIBRARIES ) + foreach(qtmod CORE ${ARGV}) + set(QUASSEL_QT_LIBRARIES ${QUASSEL_QT_LIBRARIES} ${QT_QT${qtmod}_LIBRARY} ${QT_${qtmod}_LIB_DEPENDENCIES}) + endforeach(qtmod ${ARGV}) + set(QUASSEL_QT_LIBRARIES ${QUASSEL_QT_LIBRARIES} ${QT_LIBRARIES}) +endmacro(setup_qt4_variables) + +# Now we have everything, so just glue the right pieces together :) +if(BUILD_CORE) + setup_qt4_variables(NETWORK SCRIPT SQL) + add_executable(quasselcore ${CMAKE_SOURCE_DIR}/src/common/main.cpp + ${RC_SQL} ${RC_I18N} ${WIN32_RC}) + set_target_properties(quasselcore PROPERTIES + COMPILE_FLAGS "-DQT_NETWORK_LIB -DQT_SCRIPT_LIB -DQT_SQL_LIB -DBUILD_CORE") + target_link_libraries(quasselcore mod_core mod_common ${QUASSEL_QT_LIBRARIES}) +endif(BUILD_CORE) + +if(BUILD_QTCLIENT) + setup_qt4_variables(GUI NETWORK) + add_executable(quasselclient ${CMAKE_SOURCE_DIR}/src/common/main.cpp + ${RC_ICONS} ${RC_QUASSEL_ICONS} ${RC_I18N} ${WIN32_RC}) + set_target_properties(quasselclient PROPERTIES + COMPILE_FLAGS "-DQT_GUI_LIB -DQT_NETWORK_LIB -DBUILD_QTUI") + target_link_libraries(quasselclient mod_qtui mod_uisupport mod_client mod_common ${QUASSEL_QT_LIBRARIES}) +endif(BUILD_QTCLIENT) + +if(BUILD_MONO) + setup_qt4_variables(GUI NETWORK SCRIPT SQL) + add_executable(quassel ${CMAKE_SOURCE_DIR}/src/common/main.cpp + ${RC_ICONS} ${RC_QUASSEL_ICONS} ${RC_SQL} ${RC_I18N} ${WIN32_RC}) + set_target_properties(quassel PROPERTIES + COMPILE_FLAGS "-DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_SCRIPT_LIB -DQT_SQL_LIB -DBUILD_MONO") + target_link_libraries(quassel mod_qtui mod_uisupport mod_client mod_core mod_common ${QUASSEL_QT_LIBRARIES}) +endif(BUILD_MONO) + +# Build bundles for MacOSX +if(APPLE) + add_custom_command(TARGET quasselclient POST_BUILD + COMMAND ${CMAKE_SOURCE_DIR}/scripts/build/macosx_makebundle.py + ${CMAKE_SOURCE_DIR} "Quassel Client" quasselclient) + add_custom_command(TARGET quassel POST_BUILD + COMMAND ${CMAKE_SOURCE_DIR}/scripts/build/macosx_makebundle.py + ${CMAKE_SOURCE_DIR} "Quassel" quassel) +endif(APPLE) diff --git a/README.cmake b/README.cmake new file mode 100644 index 00000000..28a6c399 --- /dev/null +++ b/README.cmake @@ -0,0 +1,53 @@ +CMake supports and encourages out-of-source builds, which do not clutter the source directory. +You can (and should) thus use an arbitrary directory for building. +There is no "make distclean"; "make clean" should usually be enough since CMake actually +cleans up properly (qmake often didn't). If you really want to get rid of all build files, +just remove the build directory. + +Usually, you will build Quassel as follows: + +cd /path/to/build/dir +cmake /path/to/quassel +make + +Additionally, you may add some options to the cmake call, prefixed by -D. These need to follow +the source directory PATH: + +cmake /path/to/quassel -D -D + +NOTE: In order to reconfigure, you need to remove CMakeCache.txt (or empty + the build directory), otherwise cmake will ignore modified -D options! + +Quassel recognizes the following options: + +-DBUILD= + Specify which Quassel binaries to build. may contain any combination of + "core", "client", "mono" or "all". + +-DQT=/path/to/qt + Use a non-system Qt installation. This is for example useful if you have a static + Qt installed in some local dir. + +-DSTATIC=1 + Enable static building of Quassel. You should link the static versions of some libs + (in particular libstdc++.a) into /path/to/build/dir/staticlibs in oder to create + a portable binary! + +-DSTATICWIN=1 + Enable static building for Windows platforms. This adds some libs that are not automatically + included for some reason. + +BUILDING ON WINDOWS: +-------------------- +We have tested building on Windows with a statically built Qt (with its /bin directory in %PATH%) +and MSVC 2005/2008. Make sure that you use a "shell" that has all needed env variables setup, +such as the "Visual Studio Command Prompt". You will also need the /bin of the Microsoft SDK in +your %PATH% at least for VS 2008, otherwise rc.exe is not found. +Currently, only building in the shell using nmake seems to work; CMake can also create MSVC project +files, but they seem to be problematic. However, YMMV. + +After you have everything setup: + +cd C:\path\to\quassel-build +cmake -G"NMake Makefiles" C:\path\to\quassel\source -DSTATICWIN=1 +nmake diff --git a/scripts/build/Info.plist b/scripts/build/Info.plist new file mode 100644 index 00000000..fbc7ac19 --- /dev/null +++ b/scripts/build/Info.plist @@ -0,0 +1,35 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + %(BUNDLE_NAME)s + CFBundleGetInfoString + Quassel IRC Client + CFBundleIconFile + %(ICON_FILE)s + CFBundleIdentifier + org.quassel-irc.client + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Quassel IRC Client + CFBundlePackageType + APPL + CFBundleShortVersionString + %(BUNDLE_VERSION)s + CFBundleSignature + ???? + CFBundleVersion + %(BUNDLE_VERSION)s + + LSRequiresCarbon + + NSHumanReadableCopyright + © 2005-08, Quassel IRC Team + + diff --git a/scripts/build/macosx_makebundle.py b/scripts/build/macosx_makebundle.py new file mode 100755 index 00000000..821ce74e --- /dev/null +++ b/scripts/build/macosx_makebundle.py @@ -0,0 +1,56 @@ +#!/usr/bin/python +# -*- coding: iso-8859-1 -*- + +# ============================== +# Imports +# ============================== +import os +import sys + +# ============================== +# Constants +# ============================== +if len(sys.argv) < 2: + sys.exit(1) + +SOURCE_DIR = sys.argv[1] + +if len(sys.argv) < 4: + BUNDLE_NAME= "Quassel Client" + EXE_NAME = "quasselclient" +else: + BUNDLE_NAME = sys.argv[2] + EXE_NAME = sys.argv[3] +CONTENTS_DIR = BUNDLE_NAME + ".app/Contents/" + +BUNDLE_VERSION = "0.2.0-pre" +ICON_FILE = "src/icons/quassel/quassel.icns" + +def createBundle(): + try: + os.makedirs(CONTENTS_DIR + "MacOS") + os.makedirs(CONTENTS_DIR + "Resources") + except: + pass + +def copyFiles(exeFile, iconFile): + os.system("cp %s %sMacOs/%s" % (exeFile, CONTENTS_DIR.replace(' ', '\ '), BUNDLE_NAME.replace(' ', '\ '))) + os.system("cp %s/%s %s/Resources" % (SOURCE_DIR, iconFile, CONTENTS_DIR.replace(' ', '\ '))) + +def createPlist(bundleName, iconFile, bundleVersion): + templateFile = file(SOURCE_DIR + "/scripts/build/Info.plist", 'r') + template = templateFile.read() + templateFile.close() + print + + plistFile = file(CONTENTS_DIR + "Info.plist", 'w') + plistFile.write(template % {"BUNDLE_NAME" : bundleName, + "ICON_FILE" : iconFile[iconFile.rfind("/")+1:], + "BUNDLE_VERSION" : bundleVersion}) + plistFile.close() + +if __name__ == "__main__": + createBundle() + createPlist(BUNDLE_NAME, ICON_FILE, BUNDLE_VERSION) + copyFiles(EXE_NAME, ICON_FILE) + pass diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt new file mode 100644 index 00000000..39436cb6 --- /dev/null +++ b/src/client/CMakeLists.txt @@ -0,0 +1,48 @@ +# Builds the client module + +# We still have some minor deps to QtUi: QItemSelectionModel +# set(QT_DONT_USE_QTGUI 1) +set(QT_USE_QTNETWORK 1) +include(${QT_USE_FILE}) + +set(SOURCES + buffer.cpp + buffermodel.cpp + buffersettings.cpp + client.cpp + clientbacklogmanager.cpp + clientsettings.cpp + clientsyncer.cpp + mappedselectionmodel.cpp + networkmodel.cpp + selectionmodelsynchronizer.cpp + treemodel.cpp) + +set(MOC_HDRS + buffer.h + buffermodel.h + client.h + clientbacklogmanager.h + clientsyncer.h + networkmodel.h + mappedselectionmodel.h + quasselui.h + selectionmodelsynchronizer.h + treemodel.h) + +set(HEADERS + buffersettings.h + clientsettings.h) + +if(SPUTDEV) + set(SOURCES ${SOURCES} messagefilter.cpp messagemodel.cpp) + set(MOC_HDRS ${MOC_HDRS} messagefilter.h messagemodel.h) +endif(SPUTDEV) + +qt4_wrap_cpp(MOC ${MOC_HDRS}) + +include_directories(${CMAKE_SOURCE_DIR}/src/common) + +add_library(mod_client STATIC ${SOURCES} ${MOC} ${HEADERS}) +add_dependencies(mod_client mod_common) + diff --git a/src/client/clientsyncer.cpp b/src/client/clientsyncer.cpp index e7f68b01..93d73bb6 100644 --- a/src/client/clientsyncer.cpp +++ b/src/client/clientsyncer.cpp @@ -157,8 +157,9 @@ void ClientSyncer::coreSocketConnected() { QVariantMap clientInit; clientInit["MsgType"] = "ClientInit"; clientInit["ClientVersion"] = Global::quasselVersion; - clientInit["ClientDate"] = Global::quasselDate; - clientInit["ClientBuild"] = Global::quasselBuild; // this is a minimum, since we probably won't update for every commit + clientInit["ClientBuild"] = 860; // FIXME legacy! + clientInit["ClientDate"] = Global::quasselBuildDate; + clientInit["ProtocolVersion"] = Global::protocolVersion; clientInit["UseSsl"] = coreConnectionInfo["useSsl"]; #ifndef QT_NO_COMPRESS clientInit["UseCompression"] = true; @@ -166,7 +167,6 @@ void ClientSyncer::coreSocketConnected() { clientInit["UseCompression"] = false; #endif - SignalProxy::writeDataToDevice(socket, clientInit); } @@ -186,9 +186,10 @@ void ClientSyncer::coreSocketDisconnected() { void ClientSyncer::clientInitAck(const QVariantMap &msg) { // Core has accepted our version info and sent its own. Let's see if we accept it as well... - if(msg["CoreBuild"].toUInt() < Global::coreBuildNeeded) { + if(msg.contains("CoreBuild") && msg["CoreBuild"].toUInt() < 732 // legacy! + || !msg.contains("CoreBuild") && msg["ProtocolVersion"].toUInt() < Global::clientNeedsProtocol) { emit connectionError(tr("The Quassel Core you are trying to connect to is too old!
" - "Need at least a Core Version %1 (Build >= %2) to connect.").arg(Global::quasselVersion).arg(Global::coreBuildNeeded)); + "Need at least core/client protocol v%1 to connect.").arg(Global::clientNeedsProtocol)); disconnectFromCore(); return; } diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt new file mode 100644 index 00000000..3b1f2ab1 --- /dev/null +++ b/src/common/CMakeLists.txt @@ -0,0 +1,52 @@ +# Builds the common module + +set(QT_DONT_USE_QTGUI 1) +set(QT_USE_QTNETWORK 1) +include(${QT_USE_FILE}) + +set(SOURCES + backlogmanager.cpp + bufferinfo.cpp + buffersyncer.cpp + bufferviewconfig.cpp + bufferviewmanager.cpp + global.cpp + identity.cpp + logger.cpp + message.cpp + settings.cpp + signalproxy.cpp + syncableobject.cpp + util.cpp + network.cpp + ircuser.cpp + ircchannel.cpp) + +set(MOC_HDRS + backlogmanager.h + buffersyncer.h + bufferviewconfig.h + bufferviewmanager.h + identity.h + ircchannel.h + ircuser.h + logger.h + network.h + signalproxy.h + syncableobject.h) + +set(HEADERS ${MOC_HDRS} + bufferinfo.h + global.h + message.h + settings.h + types.h + util.h) + +qt4_wrap_cpp(MOC ${MOC_HDRS}) + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) # for version.inc and version.gen +add_definitions(-DHAVE_VERSION_GEN) # we ensure that by deps in the main CMakeLists.txt +set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES version.gen) + +add_library(mod_common STATIC ${SOURCES} ${MOC}) diff --git a/src/common/genversion.cpp b/src/common/genversion.cpp new file mode 100644 index 00000000..e8e75f9f --- /dev/null +++ b/src/common/genversion.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (C) 2005-08 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/** This is called at compile time and generates a suitable version.gen. + * usage: genversion git_root target_file + * + */ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + if(argc < 3) { + qFatal("Usage: ./genversion "); + return 255; + } + QString gitroot = argv[1]; + QString target = argv[2]; + QString version; + + if(QFile::exists(gitroot + "/.git")) { + // try to execute git-describe to get a version string + QProcess git; + git.setWorkingDirectory(gitroot); + git.start("git-describe", QStringList("--long")); + if(git.waitForFinished(10000)) { + QString gitversion = git.readAllStandardOutput(); + if(!gitversion.isEmpty() && !gitversion.contains("fatal")) { + // seems we have a valid version string, now prettify it... + // check if the workdir is dirty first + QString dirty; + QStringList params = QStringList() << "--name-only" << "HEAD"; + git.start("git-diff-index", params); + if(git.waitForFinished(10000)) { + if(!git.readAllStandardOutput().isEmpty()) dirty = "*"; + } + // 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)); + if(!gitversion.isEmpty()) version = gitversion; + } + } + } + if(version.isEmpty()) { + // hmm, Git failed... let's check for version.dist instead + QFile dist(gitroot + "/version.dist"); + if(dist.open(QIODevice::ReadOnly | QIODevice::Text)) { + version = dist.readAll(); + dist.close(); + } + } + // ok, create our version.gen now + QFile gen(target); + if(!gen.open(QIODevice::WriteOnly | QIODevice::Text)) { + qFatal(QString("Could not write %1!").arg(target).toAscii()); + return 255; + } + gen.write(QString("quasselGeneratedVersion = \"%1\";\n" + "quasselBuildDate = \"%2\";\n" + "quasselBuildTime = \"%3\";\n").arg(version).arg(__DATE__).arg(__TIME__).toAscii()); + gen.close(); + return EXIT_SUCCESS; +} diff --git a/src/common/global.cpp b/src/common/global.cpp index 59afde13..8941d5b8 100644 --- a/src/common/global.cpp +++ b/src/common/global.cpp @@ -98,15 +98,35 @@ void Global::registerMetaTypes() { qRegisterMetaTypeStreamOperators("MsgId"); } +//! This includes version.inc and possibly version.gen and sets up our version numbers. +void Global::setupVersion() { + +# include "version.inc" +# ifdef HAVE_VERSION_GEN +# include "version.gen" +# endif + + if(quasselGeneratedVersion.isEmpty()) { + quasselVersion = QString("v%1 (unknown rev)").arg(quasselBaseVersion); + } else { + QStringList parts = quasselGeneratedVersion.split(':'); + quasselVersion = QString("v%1").arg(parts[0]); + if(parts.count() >= 2) quasselVersion.append(QString(" (%1)").arg(parts[1])); + } + quasselBuildDate = __DATE__; + quasselBuildTime = __TIME__; +} + // Static variables QString Global::quasselVersion; -QString Global::quasselDate; -uint Global::quasselBuild; -uint Global::clientBuildNeeded; -QString Global::clientVersionNeeded; -uint Global::coreBuildNeeded; -QString Global::coreVersionNeeded; +QString Global::quasselBaseVersion; +QString Global::quasselGeneratedVersion; +QString Global::quasselBuildDate; +QString Global::quasselBuildTime; +uint Global::protocolVersion; +uint Global::clientNeedsProtocol; +uint Global::coreNeedsProtocol; Global::RunMode Global::runMode; uint Global::defaultPort; diff --git a/src/common/global.h b/src/common/global.h index 0759c27e..777be215 100644 --- a/src/common/global.h +++ b/src/common/global.h @@ -33,16 +33,15 @@ namespace Global { extern QString quasselVersion; - extern QString quasselDate; - extern uint quasselBuild; + extern QString quasselBaseVersion; + extern QString quasselBuildDate; + extern QString quasselBuildTime; + extern uint protocolVersion; - //! Minimum client build number the core needs - extern uint clientBuildNeeded; - extern QString clientVersionNeeded; + extern uint clientNeedsProtocol; //< Minimum protocol version the client needs + extern uint coreNeedsProtocol; //< Minimum protocol version the core needs - //! Minimum core build number the client needs - extern uint coreBuildNeeded; - extern QString coreVersionNeeded; + extern QString quasselGeneratedVersion; //< This is possibly set in version.gen // We need different config (QSettings) files for client and gui, since the core cannot work with GUI types // Set these here. They're used in ClientSettings and CoreSettings. @@ -56,6 +55,7 @@ namespace Global { extern bool DEBUG; void registerMetaTypes(); + void setupVersion(); }; #endif diff --git a/src/common/main.cpp b/src/common/main.cpp index 3c36a280..eca54ba2 100644 --- a/src/common/main.cpp +++ b/src/common/main.cpp @@ -66,8 +66,7 @@ int main(int argc, char **argv) { // Logger logger; Global::registerMetaTypes(); - -#include "../../version.inc" + Global::setupVersion(); #if defined BUILD_CORE Global::runMode = Global::CoreOnly; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 00000000..37110f3e --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1,62 @@ +# Builds the core module + +set(QT_DONT_USE_QTGUI 1) +set(QT_USE_QTNETWORK 1) +set(QT_USE_QTSQL 1) +set(QT_USE_QTSCRIPT 1) +include(${QT_USE_FILE}) + +set(SOURCES + abstractsqlstorage.cpp + basichandler.cpp + core.cpp + corebacklogmanager.cpp + corebufferviewconfig.cpp + corebufferviewmanager.cpp + coresession.cpp + coresettings.cpp + coreusersettings.cpp + ctcphandler.cpp + ircserverhandler.cpp + networkconnection.cpp + sessionthread.cpp + sqlitestorage.cpp + storage.cpp + userinputhandler.cpp) + +set(MOC_HDRS + abstractsqlstorage.h + basichandler.h + core.h + corebacklogmanager.h + corebufferviewconfig.h + corebufferviewmanager.h + coresession.h + ctcphandler.h + ircserverhandler.h + networkconnection.h + sqlitestorage.h + storage.h + sessionthread.h + userinputhandler.h) + +set(HEADERS + coresettings.h + coreusersettings.h) + +# QT_DEFINITIONS actually does not work, stuff gets included always. +# Funny enough that does not seem to be harmful, but we should still find a way to figure out +# if we have openssl in Qt... +if(OPENSSL_FOUND AND NOT QT_DEFINITIONS MATCHES "-DQT_NO_OPENSSL") + set(SOURCES ${SOURCES} sslserver.cpp) + set(MOC_HDRS ${MOC_HDRS} sslserver.h) + link_libraries(${OPENSSL_LIBRARIES}) + include_directories(${OPENSSL_INCLUDE_DIR}) +endif(OPENSSL_FOUND AND NOT QT_DEFINITIONS MATCHES "-DQT_NO_OPENSSL") + +QT4_WRAP_CPP(MOC ${MOC_HDRS}) + +include_directories(${CMAKE_SOURCE_DIR}/src/common) + +add_library(mod_core STATIC ${SOURCES} ${MOC} ${HEADERS}) +add_dependencies(mod_core mod_common) diff --git a/src/core/core.cpp b/src/core/core.cpp index f413bbf2..ebfe4914 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -100,7 +100,7 @@ void Core::saveState() { QVariantMap state; QVariantList activeSessions; foreach(UserId user, instance()->sessions.keys()) activeSessions << QVariant::fromValue(user); - state["CoreBuild"] = Global::quasselBuild; + state["CoreStateVersion"] = 1; state["ActiveSessions"] = activeSessions; s.setCoreState(state); } @@ -115,11 +115,13 @@ void Core::restoreState() { return; } CoreSettings s; - uint build = s.coreState().toMap()["CoreBuild"].toUInt(); - if(build < 362) { + /* We don't check, since we are at the first version since switching to Git + uint statever = s.coreState().toMap()["CoreStateVersion"].toUInt(); + if(statever < 1) { qWarning() << qPrintable(tr("Core state too old, ignoring...")); return; } + */ QVariantList activeSessions = s.coreState().toMap()["ActiveSessions"].toList(); if(activeSessions.count() > 0) { qDebug() << "Restoring previous core state..."; @@ -382,16 +384,31 @@ void Core::processClientMessage(QTcpSocket *socket, const QVariantMap &msg) { // OK, so we have at least an init message format we can understand if(msg["MsgType"] == "ClientInit") { QVariantMap reply; + + // Just version information -- check it! + if(msg.contains("ClientBuild") && msg["ClientBuild"].toUInt() < 732 + || !msg.contains("ClientBuild") && msg["ProtocolVersion"].toUInt() < Global::coreNeedsProtocol) { + reply["MsgType"] = "ClientInitReject"; + reply["Error"] = tr("Your Quassel Client is too old!
" + "This core needs at least client/core protocol version %1.
" + "Please consider upgrading your client.").arg(Global::coreNeedsProtocol); + SignalProxy::writeDataToDevice(socket, reply); + qWarning() << qPrintable(tr("Client %1 too old, rejecting.").arg(socket->peerAddress().toString())); + socket->close(); return; + } + reply["CoreVersion"] = Global::quasselVersion; - reply["CoreDate"] = Global::quasselDate; - reply["CoreBuild"] = Global::quasselBuild; + reply["CoreDate"] = Global::quasselBuildDate; + reply["CoreBuild"] = 860; // FIXME legacy + reply["ProtocolVersion"] = Global::protocolVersion; // TODO: Make the core info configurable int uptime = startTime.secsTo(QDateTime::currentDateTime()); int updays = uptime / 86400; uptime %= 86400; int uphours = uptime / 3600; uptime %= 3600; int upmins = uptime / 60; - reply["CoreInfo"] = tr("Quassel Core Version %1 (Build ≥ %2)
" - "Up %3d%4h%5m (since %6)").arg(Global::quasselVersion).arg(Global::quasselBuild) + reply["CoreInfo"] = tr("Quassel Core Version %1
" + "Built: %2
" + "Up %3d%4h%5m (since %6)").arg(Global::quasselVersion).arg(Global::quasselBuildDate) .arg(updays).arg(uphours,2,10,QChar('0')).arg(upmins,2,10,QChar('0')).arg(startTime.toString(Qt::TextDate)); #ifndef QT_NO_OPENSSL @@ -407,23 +424,13 @@ void Core::processClientMessage(QTcpSocket *socket, const QVariantMap &msg) { #else bool supportsCompression = false; #endif - + reply["SupportSsl"] = supportSsl; reply["SupportsCompression"] = supportsCompression; // switch to ssl/compression after client has been informed about our capabilities (see below) reply["LoginEnabled"] = true; - // Just version information -- check it! - if(msg["ClientBuild"].toUInt() < Global::clientBuildNeeded) { - reply["MsgType"] = "ClientInitReject"; - reply["Error"] = tr("Your Quassel Client is too old!
" - "This core needs at least client version %1 (Build >= %2).
" - "Please consider upgrading your client.").arg(Global::quasselVersion).arg(Global::quasselBuild); - SignalProxy::writeDataToDevice(socket, reply); - qWarning() << qPrintable(tr("Client %1 too old, rejecting.").arg(socket->peerAddress().toString())); - socket->close(); return; - } // check if we are configured, start wizard otherwise if(!configured) { reply["Configured"] = false; diff --git a/src/core/ctcphandler.cpp b/src/core/ctcphandler.cpp index ba489648..a864fe64 100644 --- a/src/core/ctcphandler.cpp +++ b/src/core/ctcphandler.cpp @@ -175,8 +175,8 @@ void CtcpHandler::handlePing(CtcpType ctcptype, const QString &prefix, const QSt void CtcpHandler::handleVersion(CtcpType ctcptype, const QString &prefix, const QString &target, const QString ¶m) { Q_UNUSED(target) if(ctcptype == CtcpQuery) { - reply(nickFromMask(prefix), "VERSION", QString("Quassel IRC (v%1 build >= %2) -- http://www.quassel-irc.org") - .arg(Global::quasselVersion).arg(Global::quasselBuild)); + reply(nickFromMask(prefix), "VERSION", QString("Quassel IRC %1 (built on %2) -- http://www.quassel-irc.org") + .arg(Global::quasselVersion).arg(Global::quasselBuildDate)); emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Received CTCP VERSION request by %1").arg(prefix)); } else { // display Version answer diff --git a/src/icons/win32.rc b/src/icons/win32.rc new file mode 100644 index 00000000..4318d061 --- /dev/null +++ b/src/icons/win32.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "quassel/quassel.ico" \ No newline at end of file diff --git a/src/qtui/CMakeLists.txt b/src/qtui/CMakeLists.txt new file mode 100644 index 00000000..89da3d23 --- /dev/null +++ b/src/qtui/CMakeLists.txt @@ -0,0 +1,110 @@ +# Builds the qtui module + +set(QT_DONT_USE_QTGUI 0) +set(QT_USE_QTNETWORK 1) +include(${QT_USE_FILE}) + +set(SOURCES + aboutdlg.cpp + bufferwidget.cpp + coreconfigwizard.cpp + coreconnectdlg.cpp + configwizard.cpp + debugconsole.cpp + inputwidget.cpp + jumpkeyhandler.cpp + mainwin.cpp + nicklistwidget.cpp + qtui.cpp + qtuisettings.cpp + qtuistyle.cpp + settingsdlg.cpp + settingspagedlg.cpp + titlesetter.cpp + topicbutton.cpp + topicwidget.cpp + verticaldock.cpp) + +set(MOC_HDRS + aboutdlg.h + bufferwidget.h + coreconfigwizard.h + coreconnectdlg.h + debugconsole.h + inputwidget.h + jumpkeyhandler.h + mainwin.h + nicklistwidget.h + qtui.h + settingsdlg.h + settingspagedlg.h + titlesetter.h + topicbutton.h + topicwidget.h + verticaldock.h) + +set(HEADERS + qtuisettings.h + qtuistyle.h) + +if(SPUTDEV) + set(SOURCES ${SOURCES} chatitem.cpp chatline.cpp chatlinemodelitem.cpp + chatlinemodel.cpp chatscene.cpp chatview.cpp) + set(MOC_HDRS ${MOC_HDRS} chatlinemodel.h chatscene.h chatview.h) + set(HEADERS ${HEADERS} chatitem.h chatline.h chatlinemodelitem.h) +else(SPUTDEV) + set(SOURCES ${SOURCES} chatline-old.cpp chatwidget.cpp) + set(MOC_HDRS ${MOC_HDRS} chatline-old.h chatwidget.h) +endif(SPUTDEV) + +set(FORMS + aboutdlg.ui + bufferviewwidget.ui + bufferwidget.ui + coreaccounteditdlg.ui + coreconfigwizardintropage.ui + coreconfigwizardadminuserpage.ui + coreconfigwizardstorageselectionpage.ui + coreconfigwizardsyncpage.ui + coreconnectdlg.ui + debugconsole.ui + inputwidget.ui + mainwin.ui + nicklistwidget.ui + settingsdlg.ui + settingspagedlg.ui + topicwidget.ui) + +foreach(FORM ${FORMS}) + set(FORMPATH ${FORMPATH} ui/${FORM}) +endforeach(FORM ${FORMS}) + +# handle settingspages +include(settingspages/settingspages.inc) +foreach(SP ${SETTINGSPAGES}) + set(SPSRC ${SPSRC} settingspages/${SP}settingspage.cpp) + set(SPHDR ${SPHDR} settingspages/${SP}settingspage.h) + set(SPFRM ${SPFRM} settingspages/${SP}settingspage.ui) +endforeach(SP ${SETTINGSPAGES}) +foreach(SRC ${SP_SOURCES}) + set(SPSRC ${SPSRC} settingspages/${SRC}) +endforeach(SRC ${SP_SOURCES}) +foreach(HDR ${SP_HEADERS}) + set(SPHDR ${SPHDR} settingspages/${HDR}) +endforeach(HDR ${SP_HEADERS}) +foreach(FRM ${SP_FORMS}) + set(SPFRM ${SPFRM} settingspages/${FRM}) +endforeach(FRM ${SP_FORMS}) + + +qt4_wrap_cpp(MOC ${MOC_HDRS} ${SPHDR}) +qt4_wrap_ui(UI ${FORMPATH} ${SPFRM}) + +include_directories(${CMAKE_SOURCE_DIR}/src/common + ${CMAKE_SOURCE_DIR}/src/client + ${CMAKE_SOURCE_DIR}/src/qtui + ${CMAKE_SOURCE_DIR}/src/uisupport + ${CMAKE_CURRENT_BINARY_DIR}) + +add_library(mod_qtui STATIC ${SOURCES} ${SPSRC} ${MOC} ${UI} ${HEADERS}) +add_dependencies(mod_qtui mod_common mod_client mod_uisupport) diff --git a/src/qtui/aboutdlg.cpp b/src/qtui/aboutdlg.cpp index a32ab6b8..0c55277e 100644 --- a/src/qtui/aboutdlg.cpp +++ b/src/qtui/aboutdlg.cpp @@ -24,7 +24,8 @@ AboutDlg::AboutDlg(QWidget *parent) : QDialog(parent) { ui.setupUi(this); - ui.versionLabel->setText(QString("Version %1, Build ≥ %2 (%3)").arg(Global::quasselVersion).arg(Global::quasselBuild).arg(Global::quasselDate)); + ui.versionLabel->setText(QString("Version %1
Built: %2 %3").arg(Global::quasselVersion) + .arg(Global::quasselBuildDate).arg(Global::quasselBuildTime)); ui.aboutTextBrowser->setHtml(about()); ui.authorTextBrowser->setHtml(authors()); ui.contributorTextBrowser->setHtml(contributors()); diff --git a/src/qtui/settingspages/settingspages.inc b/src/qtui/settingspages/settingspages.inc new file mode 100644 index 00000000..b3d93b66 --- /dev/null +++ b/src/qtui/settingspages/settingspages.inc @@ -0,0 +1,8 @@ +# Putting $FOO in SETTINGSPAGES automatically includes +# $FOOsettingspage.cpp, $FOOsettingspage.h and $FOOsettingspage.ui +set(SETTINGSPAGES appearance bufferview color fonts general highlight identities networks) + +# Specify additional files (e.g. for subdialogs) here! +set(SP_SOURCES ) +set(SP_HEADERS ) +set(SP_FORMS buffervieweditdlg.ui createidentitydlg.ui saveidentitiesdlg.ui networkeditdlg.ui nickeditdlg.ui servereditdlg.ui) diff --git a/src/uisupport/CMakeLists.txt b/src/uisupport/CMakeLists.txt new file mode 100644 index 00000000..ad63477d --- /dev/null +++ b/src/uisupport/CMakeLists.txt @@ -0,0 +1,53 @@ +# Builds the uisupport module + +set(QT_DONT_USE_QTGUI 0) +set(QT_USE_QTNETWORK 1) +include(${QT_USE_FILE}) + +set(SOURCES + abstractbuffercontainer.cpp + abstractitemview.cpp + bufferview.cpp + bufferviewfilter.cpp + clearablelineedit.cpp + colorbutton.cpp + nickviewfilter.cpp + inputline.cpp + nickview.cpp + settingspage.cpp + tabcompleter.cpp + uisettings.cpp + uistylesettings.cpp) + +set(MOC_HDRS + abstractbuffercontainer.h + abstractitemview.h + bufferview.h + bufferviewfilter.h + clearablelineedit.h + colorbutton.h + nickviewfilter.h + inputline.h + nickview.h + settingspage.h + tabcompleter.h) + +set(HEADERS + uisettings.h + uistylesettings.h) + +if(SPUTDEV) + set(SOURCES ${SOURCES} uistyle.cpp) + set(HEADERS ${HEADERS} uistyle.h) +else(SPUTDEV) + set(SOURCES ${SOURCES} old-uistyle.cpp) + set(HEADERS ${HEADERS} old-uistyle.h) +endif(SPUTDEV) + +qt4_wrap_cpp(MOC ${MOC_HDRS}) + +include_directories(${CMAKE_SOURCE_DIR}/src/common + ${CMAKE_SOURCE_DIR}/src/client) + +add_library(mod_uisupport STATIC ${SOURCES} ${MOC} ${HEADERS}) +add_dependencies(mod_uisupport mod_common mod_client) diff --git a/version.inc b/version.inc index 10b10a62..92fc5fd5 100644 --- a/version.inc +++ b/version.inc @@ -1,18 +1,9 @@ // Versioning, should be kept current :) // This is included in main.cpp -{ using namespace Global; +//! This is the fallback version number in case we can't autogenerate one +quasselBaseVersion = "0.3.0-pre"; +protocolVersion = 1; //< Version of the client/core protocol - quasselVersion = "0.3.0-pre"; - quasselDate = "2008-06-04"; - quasselBuild = 869; - - //! Minimum client build number the core needs - clientBuildNeeded = 731; - clientVersionNeeded = quasselVersion; - - //! Minimum core build number the client needs - coreBuildNeeded = 731; - coreVersionNeeded = quasselVersion; - -} +coreNeedsProtocol = 1; //< Minimum protocol version the core needs +clientNeedsProtocol = 1; //< Minimum protocol version the client needs