1996557617d7327b9c5e4d826da0ca1dc114a02f
[quassel.git] / CMakeLists.txt
1 # Main CMake file for building Quassel IRC
2 #
3 # See INSTALL for possible CMake options (or read the code, Luke)
4 #####################################################################
5
6 # General setup
7 #####################################################################
8
9 cmake_minimum_required(VERSION 2.8.9)
10 project(QuasselIRC)
11
12 # Versions
13 set(QUASSEL_MAJOR  0)
14 set(QUASSEL_MINOR 11)
15 set(QUASSEL_PATCH  0)
16 set(QUASSEL_VERSION_STRING "0.11-pre")
17
18 # Tell CMake about or own modules
19 set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
20
21 # General conveniences
22 set(CMAKE_AUTOMOC ON)
23 set(CMAKE_INCLUDE_CURRENT_DIR ON)
24
25 # Moar stuff
26 include(CheckFunctionExists)
27 include(CheckIncludeFile)
28
29 include(QuasselCompileSettings)
30 include(QuasselMacros)
31
32 include(CMakeDependentOption)
33 include(FeatureSummary)
34
35
36 # Options and variables that can be set on the command line
37 #####################################################################
38
39 # First, choose a Qt version. We support USE_QT4 and USE_QT5; if neither is set, prefer Qt4 for now
40 option(USE_QT5 "Enable support for Qt5 (disables KDE integration)" OFF)
41 if (USE_QT4) # takes precedence
42     set(USE_QT5 OFF)
43 else()
44     if (NOT USE_QT5)
45         set(USE_QT4 ON)
46     endif()
47 endif()
48
49 # Select the binaries to build
50 option(WANT_CORE     "Build the core (server) binary"           ON)
51 option(WANT_QTCLIENT "Build the Qt GUI client binary"           ON)
52 option(WANT_MONO     "Build the monolithic (all-in-one) binary" ON)
53
54 add_feature_info(WANT_CORE WANT_CORE "Build the core (server) binary")
55 add_feature_info(WANT_QTCLIENT WANT_QTCLIENT "Build the Qt GUI client binary")
56 add_feature_info(WANT_MONO WANT_MONO "Build the monolithic (all-in-one) binary")
57
58
59 # Whether to enable KDE integration (pulls in kdelibs and friends as a dependency); requires Qt4 for now
60 cmake_dependent_option(WITH_KDE      "KDE4 integration" OFF "USE_QT4" OFF)
61 add_feature_info(WITH_KDE WITH_KDE "Enable KDE4 integration")
62
63 # Some options don't make sense with KDE
64 cmake_dependent_option(WITH_PHONON   "Phonon support (for audio notifications)"           ON "NOT WITH_KDE" OFF)
65 cmake_dependent_option(WITH_SNORE    "Snore notification support"                        OFF "NOT WITH_KDE" OFF)
66 cmake_dependent_option(WITH_OXYGEN   "Install Oxygen icon set (usually shipped with KDE)" ON "NOT WITH_KDE" OFF)
67
68 # Misc features
69 option(WITH_OPENSSL     "OpenSSL support (secure networking)"             ON)
70 option(WITH_DBUS        "Use D-Bus for the tray icon (StatusNotifier)"    ON)
71 option(WITH_WEBKIT      "WebKit support (for link previews)"              ON)
72 option(WITH_CRYPT       "Encryption support (QCA)"                        ON)
73 option(WITH_LIBINDICATE "Ayatana (libindicate) notification support"      ON)
74 cmake_dependent_option(WITH_SYSLOG   "Support logging to syslog"          ON "NOT WIN32" OFF)
75
76 if (APPLE)
77     # Notification Center is only available in > 10.8, which is Darwin v12
78     if (CMAKE_SYSTEM_VERSION VERSION_GREATER "11.9.9")
79         option(WITH_NOTIFICATION_CENTER "OS X Notification Center support" ON)
80         add_feature_info(WITH_NOTIFICATION_CENTER WITH_NOTIFICATION_CENTER "Use the OS X Notification Center")
81     endif()
82 endif()
83
84 # Always embed on Windows or for a static build; never embed when enabling KDE integration
85 set(EMBED_DEFAULT OFF)
86 if (STATIC OR WIN32)
87     set(EMBED_DEFAULT ON)
88 endif()
89 cmake_dependent_option(EMBED_DATA "Embed icons and translations in the binaries instead of installing them" ${EMBED_DEFAULT}
90                                    "NOT STATIC;NOT WIN32;NOT WITH_KDE" ${EMBED_DEFAULT})
91
92 cmake_dependent_option(DEPLOY      "Add required libs to bundle resources and create a dmg. Note: requires Qt to be built with 10.4u SDK" OFF "APPLE" OFF)
93
94 # Handle with care
95 set(QT_PATH "" CACHE PATH "Path to a Qt4 installation to use instead of the system Qt (e.g. for static builds)")
96
97
98 # Static builds are not supported and require some manual setup! Don't enable unless you know what you're doing (we don't know either)
99 cmake_dependent_option(STATIC      "Enable static building (not supported)" OFF "NOT WITH_KDE" OFF)
100
101 # For static builds, arbitrary extra libs might need to be linked
102 # Define a comma-separated list here
103 # e.g. for pgsql, we need -DLINK_EXTRA=pq;crypt
104 set(LINK_EXTRA "" CACHE STRING "Semicolon-separated list of libraries to be linked")
105 if (LINK_EXTRA)
106     string(REPLACE "," ";" LINK_EXTRA ${LINK_EXTRA})
107     link_libraries(${LINK_EXTRA})
108 endif()
109
110
111 # Simplify later checks
112 #####################################################################
113
114 if (WANT_MONO OR WANT_QTCLIENT)
115     set(BUILD_GUI true)
116 endif()
117 if (WANT_MONO OR WANT_CORE)
118     set(BUILD_CORE true)
119 endif()
120
121
122 # Set up Qt
123 #####################################################################
124
125 if (USE_QT5)
126     message(STATUS "Building with the Qt5 libraries...")
127     set(QT_MIN_VERSION "5.2.0")
128     add_definitions(-DHAVE_QT5)
129 else()
130     message(STATUS "Building with the Qt4 libraries...")
131     if (BUILD_GUI)
132         set(QT_MIN_VERSION "4.6.0")
133     else()
134         set(QT_MIN_VERSION "4.4.0")
135     endif()
136 endif()
137
138 if (USE_QT5)
139     find_package(Qt5Core ${QT_MIN_VERSION} QUIET REQUIRED)
140
141     # Contains lconvert and friends
142     find_package(Qt5LinguistTools QUIET)
143     set_package_properties(Qt5LinguistTools PROPERTIES TYPE RECOMMENDED
144                            PURPOSE "Required for localization support"
145     )
146 else()
147     # Select a Qt installation here, if you don't want to use system Qt
148     if(QT_PATH)
149         # FindQt4 will look for the qmake binary in $PATH, so we just prepend QT_PATH
150         set(ENV{PATH} ${QT_PATH}/bin:$ENV{PATH})
151     endif()
152
153     # Now that we have the correct $PATH, lets find Qt!
154     find_package(Qt4 ${QT_MIN_VERSION} QUIET REQUIRED)
155 endif()
156
157 # Neither Qt4 nor Qt5 consider lconvert relevant, so they don't support finding it...
158 # Rather than shipping hacked buildsys files, let's just infer the path from lrelease
159 if (QT_LRELEASE_EXECUTABLE)
160     get_filename_component(_lrelease_path ${QT_LRELEASE_EXECUTABLE} PATH)
161     if (USE_QT5)
162         find_program(QT_LCONVERT_EXECUTABLE NAMES lconvert-qt5 lconvert PATHS ${_lrelease_path} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
163     else()
164         find_program(QT_LCONVERT_EXECUTABLE NAMES lconvert-qt4 lconvert PATHS ${_lrelease_path} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
165     endif()
166 endif()
167
168 add_feature_info("Qt Linguist Tools" QT_LRELEASE_EXECUTABLE "Translation support for Quassel")
169
170 # Optional Dependencies
171 #
172 # Note that you can forcefully disable optional packages
173 # using -DCMAKE_DISABLE_FIND_PACKAGE_<PkgName>=TRUE
174 #####################################################################
175
176 if(USE_QT5)
177     if (BUILD_GUI)
178         find_package(Qt5DBus QUIET)
179         set_package_properties(Qt5DBus PROPERTIES TYPE RECOMMENDED
180             URL "http://qt.digia.com"
181             DESCRIPTION "D-Bus support for Qt5"
182             PURPOSE     "Needed for supporting D-Bus-based notifications and tray icon, used by most modern desktop environments"
183         )
184         if (Qt5DBus_FOUND)
185             find_package(dbusmenu-qt5 QUIET)
186             set_package_properties(dbusmenu-qt5 PROPERTIES TYPE RECOMMENDED
187                 URL "https://launchpad.net/libdbusmenu-qt"
188                 DESCRIPTION "a library implementing the DBusMenu specification"
189                 PURPOSE     "Required for having a context menu for the D-Bus-based tray icon"
190             )
191         endif()
192
193         find_package(Phonon4Qt5 QUIET)
194         set_package_properties(Phonon4Qt5 PROPERTIES TYPE RECOMMENDED
195             URL "https://projects.kde.org/projects/kdesupport/phonon"
196             DESCRIPTION "a multimedia abstraction library"
197             PURPOSE     "Required for audio notifications"
198         )
199
200         if (WITH_WEBKIT)
201             find_package(Qt5Webkit QUIET)
202             set_package_properties(Qt5Webkit PROPERTIES TYPE RECOMMENDED
203                 URL "http://qt.digia.com"
204                 DESCRIPTION "a Webkit implementation for Qt"
205                 PURPOSE     "Needed for displaying previews for URLs in chat"
206             )
207         endif()
208         add_feature_info("WITH_WEBKIT and QtWebkit module" Qt5Webkit_FOUND "Support showing previews for URLs in chat")
209
210     endif(BUILD_GUI)
211     if (BUILD_CORE)
212         # While QCA2 seems to support Qt5, it is not actually co-installable or distinguishable from the Qt4 version...
213         # In order to avoid linking against the Qt4 version (which is probably the one installed), disable this for now
214         #find_package(QCA2 QUIET)
215         #set_package_properties(QCA2 PROPERTIES TYPE RECOMMENDED
216         #    URL "https://projects.kde.org/projects/kdesupport/qca"
217         #    DESCRIPTION "Qt Cryptographic Architecture"
218         #    PURPOSE "Required for encryption support"
219         #)
220
221     endif(BUILD_CORE)
222
223 else(USE_QT5)
224     if (BUILD_GUI)
225         add_feature_info("QtDBus module" QT_QTDBUS_FOUND "Needed for supporting D-Bus-based notifications and tray icon, used by most modern desktop environments")
226         if (QT_QTDBUS_FOUND)
227             find_package(libdbusmenu-qt QUIET)
228             set_package_properties(dbusmenu-qt PROPERTIES TYPE RECOMMENDED
229                 URL "https://launchpad.net/libdbusmenu-qt"
230                 DESCRIPTION "a library implementing the DBusMenu specification"
231                 PURPOSE     "Required for having a context menu for the D-Bus-based tray icon"
232             )
233         endif()
234
235         if (WITH_WEBKIT AND QT_QTWEBKIT_FOUND)
236             set(HAVE_WEBKIT true)
237         endif()
238         add_feature_info("WITH_WEBKIT and QtWebkit module" HAVE_WEBKIT "Support showing previews for URLs in chat")
239
240         if (WITH_KDE)
241             # KDE has overzealous CFLAGS making miniz not compile, so save our old flags
242             set(_cflags ${CMAKE_C_FLAGS})
243             find_package(KDE4 4.4 QUIET)
244             set_package_properties(KDE4 PROPERTIES TYPE REQUIRED
245                 URL "http://www.kde.org"
246                 DESCRIPTION "a world-class desktop environment"
247                 PURPOSE "Enables various bits for improving integration with KDE"
248             )
249             set(CMAKE_C_FLAGS ${_cflags})
250
251         else(WITH_KDE)
252             find_package(Phonon QUIET)
253             set_package_properties(Phonon PROPERTIES TYPE RECOMMENDED
254                 URL "https://projects.kde.org/projects/kdesupport/phonon"
255                 DESCRIPTION "a multimedia abstraction library"
256                 PURPOSE     "Required for audio notifications"
257             )
258
259             find_package(Libsnore QUIET)
260             set_package_properties(Libsnore PROPERTIES TYPE OPTIONAL
261                 URL "https://github.com/TheOneRing/Snorenotify"
262                 DESCRIPTION "a cross-platform notification framework"
263                 PURPOSE     "Enable support for the snorenotify framework"
264             )
265         endif(WITH_KDE)
266
267         find_package(IndicateQt QUIET)
268         set_package_properties(IndicateQt PROPERTIES TYPE OPTIONAL
269             URL "https://launchpad.net/libindicate-qt/"
270             DESCRIPTION "a library to raise flags on DBus for other components of the desktop to pick up and visualize"
271             PURPOSE     "Provides integration into the Ayatana notification system used by e.g. Ubuntu"
272         )
273
274     endif(BUILD_GUI)
275     if (BUILD_CORE)
276
277         find_package(QCA2 QUIET)
278         set_package_properties(QCA2 PROPERTIES TYPE RECOMMENDED
279             URL "https://projects.kde.org/projects/kdesupport/qca"
280             DESCRIPTION "Qt Cryptographic Architecture"
281             PURPOSE     "Required for encryption support"
282         )
283
284
285     endif()
286 endif()
287
288 # Non-Qt-based packages
289
290 # zlib for compression, however we can always fall back to miniz
291 find_package(ZLIB QUIET)
292 set_package_properties(ZLIB PROPERTIES TYPE RECOMMENDED
293     URL "http://www.zlib.net"
294     DESCRIPTION "a popular compression library"
295     PURPOSE     "Use the most common library for protocol compression, instead of the bundled miniz implementation"
296 )
297
298
299 if (NOT WIN32)
300     # Execinfo is needed for generating backtraces
301     find_package(ExecInfo QUIET)
302     set_package_properties(ExecInfo PROPERTIES TYPE OPTIONAL
303         DESCRIPTION "a library for inspecting backtraces"
304         PURPOSE "Used for generating backtraces in case of a crash"
305     )
306 endif()
307
308
309 # Various checks
310 #####################################################################
311
312 if (NOT ZLIB_FOUND)
313     message(STATUS "zlib NOT found, using bundled miniz for compression")
314     if (${CMAKE_SIZEOF_VOID_P} EQUAL 4)
315         message(STATUS "WARNING: This may be slow on 32 bit systems!")
316     endif()
317 endif()
318
319 if (KDE4_FOUND)
320     # We always use external icons for KDE4 support, since we use its iconloader rather than our own
321     set(EMBED_DATA OFF)
322
323     # Better have the compile flags global, even for the core, to avoid problems with linking the mono client
324     add_definitions(-DHAVE_KDE ${KDE4_DEFINITIONS})
325 endif()
326
327 # Check for SSL support in Qt (broken for Qt5 currently)
328 # We don't link to the OpenSSL libraries ourselves.
329 if (QT_QCONFIG MATCHES "openssl")
330     set(HAVE_SSL true)
331     add_definitions(-DHAVE_SSL)
332 endif()
333 add_feature_info("SSL support in Qt" HAVE_SSL "Use secure network connections")
334
335 # Check for syslog support
336 if (NOT WIN32)
337     check_include_file(syslog.h HAVE_SYSLOG)
338     add_feature_info("syslog.h" HAVE_SYSLOG "Provide support for logging to the syslog")
339 endif()
340
341
342 # Various settings
343 ##################
344
345 # needed to compile with mingw without kde
346 if (MINGW AND NOT KDE4_FOUND)
347     add_definitions(-D_WIN32_WINNT=0x0500)
348     message(STATUS "Added _WIN32_WINNT=0x0500 definition for MinGW")
349 # workaround for bug in mingw gcc 4.0
350     add_definitions(-U__STRICT_ANSI__)
351 endif()
352
353 # Now set up install locations; those are set by KDE if integration is enabled
354 if(NOT KDE4_FOUND)
355   if(WIN32)
356     set(BIN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX} CACHE FILEPATH "Install path for binaries")
357     set(DATA_INSTALL_DIR $ENV{APPDATA}/quassel-irc.org/share/apps CACHE FILEPATH "Install path for data files")
358     set(ICON_INSTALL_DIR $ENV{APPDATA}/quassel-irc.org/share/icons CACHE FILEPATH "Global icon install path")
359     set(XDG_APPS_INSTALL_DIR $ENV{APPDATA}/quassel-irc.org/share/applications CACHE FILEPATH "Install path for .desktop files")
360   else(WIN32)
361     set(BIN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin CACHE FILEPATH "Install path for binaries")
362     set(DATA_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/apps CACHE FILEPATH "Install path for data files")
363     set(ICON_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/icons CACHE FILEPATH "Global icon install path")
364     set(XDG_APPS_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/applications CACHE FILEPATH "Install path for .desktop files")
365   endif(WIN32)
366 endif()
367
368 if(EMBED_DATA)
369   message(STATUS "Embedding data files into the binary")
370 else(EMBED_DATA)
371   message(STATUS "Installing data files separately")
372 endif(EMBED_DATA)
373
374 # RPATH needs to be set correctly
375 # Do this down here, since otherwise KDE wants to handle it itself, and fails
376 set(CMAKE_INSTALL_RPATH_USE_LINK_PATH 1)
377 set(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
378
379 # Set global buildflags
380 # This is very much non-portable, so don't use -DSTATIC until you know what
381 # you do.
382 if(STATIC AND CMAKE_COMPILER_IS_GNUCXX)
383   set(CMAKE_CXX_FLAGS "-static-libgcc ${CMAKE_CXX_FLAGS}")
384   link_directories(${CMAKE_BINARY_DIR}/staticlibs) # override dynamic libs
385   if(HAVE_SSL)
386     set(QUASSEL_SSL_LIBRARIES ssl crypto)  # these miss in static builds
387   endif(HAVE_SSL)
388 endif(STATIC AND CMAKE_COMPILER_IS_GNUCXX)
389
390 if(WIN32)
391   link_libraries(imm32 winmm dbghelp Secur32)  # missing by default :/
392   if(MSVC)
393     set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBUGINFO "/debug /INCREMENTAL:YES /NODEFAULTLIB:libcmt /DEFAULTLIB:msvcrt")
394     set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/debug /INCREMENTAL:YES /NODEFAULTLIB:libcmt")
395     set(CMAKE_EXE_LINKER_FLAGS_DEBUGFULL "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
396     link_libraries(Version dwmapi shlwapi)
397   endif(MSVC)
398   if(HAVE_SSL AND STATIC)
399      find_package(OpenSSL REQUIRED)
400      link_libraries(${OPENSSL_LIBRARIES} ${OPENSSL_EAY_LIBRARIES})
401   endif(HAVE_SSL AND STATIC)
402 endif(WIN32)
403
404 if(INDICATEQT_FOUND)
405   add_definitions(-DXDG_APPS_INSTALL_DIR=${XDG_APPS_INSTALL_DIR})
406 endif()
407
408 if(NOT WIN32)
409   check_function_exists(umask HAVE_UMASK)
410   if(HAVE_UMASK)
411     add_definitions(-DHAVE_UMASK)
412   endif(HAVE_UMASK)
413 endif(NOT WIN32)
414
415 # Generate version information from Git
416 include(GetGitRevisionDescription)
417 get_git_head_revision(GIT_REFSPEC GIT_HEAD)
418 git_describe(GIT_DESCRIBE --long)
419
420 # Sanitize things if we're not in a Git repo
421 if(NOT GIT_HEAD OR NOT GIT_DESCRIBE)
422     set(GIT_HEAD "")
423     set(GIT_DESCRIBE "")
424 endif()
425
426 configure_file(version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY)
427
428 # These variables will be added to the main targets (CORE, QTCLIENT, MONO)
429 set(COMMON_DEPS ${RC_WIN32})
430 set(CORE_DEPS )
431 set(CLIENT_DEPS )
432
433 # Add needed subdirs - the order is important, since src needs some vars set by other dirs
434 add_subdirectory(data)
435 add_subdirectory(icons)
436 add_subdirectory(pics)
437 add_subdirectory(po)
438 add_subdirectory(src)
439
440 # Set up and display feature summary
441 #####################################################################
442
443 feature_summary(WHAT ALL
444                 INCLUDE_QUIET_PACKAGES
445                 FATAL_ON_MISSING_REQUIRED_PACKAGES
446 )