use CMAKE_DL_LIBS
[quassel.git] / CMakeLists.txt
1 # This is the cmake-based build system for Quassel IRC.
2 #
3 # You may pass various options to cmake:
4 # -DWANT_(CORE|QTCLIENT|MONO)=(ON|OFF)
5 #                        : select binaries to build
6 # -DWITH_OPENSSL=OFF     : Disable OpenSSL support
7 # -DWITH_DBUS=OFF        : Disable D-Bus support (dbus notifications)
8 # -DWITH_WEBKIT=OFF      : Disable WebKit support (link previews)
9 # -DWITH_PHONON=OFF      : Disable Phonon support (audio notifications)
10 # -DWITH_LIBINDICATE=OFF : Disable libindicate support (Ayatana notifications)
11 # -DWITH_KDE=ON          : Enable KDE4 support
12 # -DWITH_CRYPT=OFF       : Disable encryption support
13 # -DWITH_OXYGEN=(ON|OFF) : Whether to install Oxygen icons (default: yes, unless KDE > 4.3.0 is present and enabled)
14 # -DWITH_SYSLOG=OFF      : Disable syslog support
15 #
16 # -DEMBED_DATA=ON        : Embed all data files in icons the binary, rather than installing them separately
17 #
18 # -DQT=/path/to/qt       : Choose a Qt4 installation to use instead of the system Qt4
19 # -DSTATIC=ON            : Enable static building of Quassel. Use with care.
20 # -DDEPLOY=ON            : Mac OS X only. Use only for creating Quassel Packages!
21 #
22 # NOTE: You should remove CMakeCache.txt if you plan to change any of these values!
23
24 project(QuasselIRC)
25
26 include(CheckFunctionExists)
27 include(CheckIncludeFile)
28
29 # cmake 2.6.2 is required for KDE >=4.2 and should be widespread enough now
30 cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR)
31
32 if(COMMAND cmake_policy)
33    cmake_policy(SET CMP0003 NEW)
34 endif(COMMAND cmake_policy)
35
36 # Use our own (well, and KDE's) version of some modules
37 # In particular cmake's own FindQt4 and FindOpenSSL are quite buggy
38 set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
39 include(QuasselMacros)
40
41 # Various options and variables that can be set on the command line
42 option(WANT_CORE     "Build the core (server) binary"           ON)
43 option(WANT_QTCLIENT "Build the Qt4 GUI client binary"          ON)
44 option(WANT_MONO     "Build the monolithic (all-in-one) binary" ON)
45
46 option(WITH_OPENSSL  "Enable OpenSSL support if present on the system"  ON)
47 option(WITH_DBUS     "Enable D-Bus support if present on the system"    ON)
48 option(WITH_WEBKIT   "Enable WebKit support (for link previews)"        ON)
49 option(WITH_PHONON   "Enable Phonon support (for audio notifications)"  ON)
50 option(WITH_LIBINDICATE "Enable Ayatana notification support"           ON)
51 option(WITH_KDE      "Enable KDE4 integration"                          OFF)
52 option(WITH_CRYPT    "Enable encryption support if present on system"   ON)
53 option(WITH_SYSLOG   "Use syslog for storing log data"                  ON)
54
55 # We use icon paths from KDE 4.3.x, which are partially invalid on older and possibly
56 # even on newer KDE versions. Do not disable this unless you are sure that your Quassel will
57 # run on a matching KDE version only.
58 set(WITH_OXYGEN AUTO CACHE STRING "Install Oxygen icons (default is \"AUTO\" to install when KDE 4.3 or later is present")
59
60 option(STATIC        "Enable static building (might not be portable)" OFF)
61
62 if(APPLE)
63   option(DEPLOY        "Mac OS X only! Adds required libs to bundle resources and create a dmg. Note: requires Qt to be built with 10.4u SDK" OFF)
64 endif(APPLE)
65
66 # Default to embedding data in the static case
67 if(STATIC OR WIN32)
68   set(EMBED_DEFAULT ON)
69 else(STATIC OR WIN32)
70   set(EMBED_DEFAULT ON) # should be OFF as soon as everything works
71 endif(STATIC OR WIN32)
72
73 option(EMBED_DATA    "Embed all data files in the binary (rather than installing them separately)"   ${EMBED_DEFAULT})
74
75 set(QT "" CACHE STRING "Path to a Qt installation to use instead of the system Qt (e.g. for static builds)")
76
77 # Some settings imply others
78 if(STATIC)
79   add_definitions(-DSTATIC)
80   set(WITH_KDE OFF CACHE BOOL "Static building with KDE is not supported")
81 endif(STATIC)
82
83 if(WIN32)
84   # We don't support separately installed resources yet on Win32
85   set(EMBED_DATA ON)
86 endif(WIN32)
87
88 # For static builds, arbitrary extra libs might need to be linked
89 # Define a comma-separated list here
90 # e.g. for pgsql, we need -DLINK_EXTRA=pq;crypt
91 set(LINK_EXTRA "" CACHE STRING "Semicolon-separated list of libraries to be linked")
92 if(LINK_EXTRA)
93   string(REPLACE "," ";" LINK_EXTRA ${LINK_EXTRA})
94   link_libraries(${LINK_EXTRA})
95 endif(LINK_EXTRA)
96
97 # Build Type
98 # We need to make sure it's not empty
99 # Supported: Release, RelWithDebugInfo, Debug, Debugfull
100
101 # On WIN32, only Release seems to work correctly (?)
102 if(WIN32)
103   set(DEFAULT_BUILD_TYPE "Release")
104 else(WIN32)
105   set(DEFAULT_BUILD_TYPE "RelWithDebugInfo")
106 endif(WIN32)
107
108 set(CMAKE_BUILD_TYPE ${DEFAULT_BUILD_TYPE} CACHE STRING "CMake Build Type")
109 if(NOT CMAKE_BUILD_TYPE)
110   set(CMAKE_BUILD_TYPE ${DEFAULT_BUILD_TYPE} CACHE STRING "CMake Build Type" FORCE)
111 endif(NOT CMAKE_BUILD_TYPE)
112
113 # Enable various flags on gcc
114 if(CMAKE_COMPILER_IS_GNUCXX)
115   # Let's just hope that all gccs support these options and skip the tests...
116   # -fno-strict-aliasing is needed apparently for Qt < 4.6
117   set(CMAKE_CXX_FLAGS                  "${CMAKE_CXX_FLAGS} -ansi -Wall -Wextra -Wnon-virtual-dtor -fno-strict-aliasing")
118   set(CMAKE_CXX_FLAGS_RELEASE          "-O2 ${CMAKE_CXX_FLAGS}")
119   set(CMAKE_CXX_FLAGS_RELWITHDEBUGINFO "-g -O2 ${CMAKE_CXX_FLAGS}")
120   set(CMAKE_CXX_FLAGS_DEBUG            "-g -ggdb -fno-reorder-blocks -fno-schedule-insns -fno-inline ${CMAKE_CXX_FLAGS}")
121   set(CMAKE_CXX_FLAGS_DEBUGFULL        "-g3 ${CMAKE_CXX_FLAGS_DEBUG}")
122 endif(CMAKE_COMPILER_IS_GNUCXX)
123
124 string(TOUPPER ${CMAKE_BUILD_TYPE} upper_build_type)
125 if(upper_build_type STREQUAL "RELEASE" OR upper_build_type STREQUAL "RELWITHDEBUGINFO")
126   add_definitions(-DNDEBUG -DQT_NO_DEBUG)
127 else(upper_build_type STREQUAL "RELEASE" OR upper_build_type STREQUAL "RELWITHDEBUGINFO")
128   set(DEBUG 1)
129 endif(upper_build_type STREQUAL "RELEASE" OR upper_build_type STREQUAL "RELWITHDEBUGINFO")
130
131 if(APPLE AND DEPLOY)
132   set(CMAKE_OSX_ARCHITECTURES "i386;ppc")
133   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.4")
134   set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.4u.sdk/")
135   add_definitions(-DMAC_10_4_SDK)
136 endif(APPLE AND DEPLOY)
137
138 # Simplify checks
139 if(WANT_MONO OR WANT_QTCLIENT)
140   set(BUILD_GUI true)
141 endif(WANT_MONO OR WANT_QTCLIENT)
142 if(WANT_MONO OR WANT_CORE)
143   set(BUILD_CORE true)
144 endif(WANT_MONO OR WANT_CORE)
145
146 # Dependencies
147 ##############
148
149 # GUI stuff needs some new features
150 if(BUILD_GUI)
151   set(QT_MIN_VERSION "4.6.0")
152 else(BUILD_GUI)
153   set(QT_MIN_VERSION "4.4.0")
154 endif(BUILD_GUI)
155
156 # Execinfo is needed for generating backtraces
157 find_package(ExecInfo)
158 if(EXECINFO_FOUND)
159   add_definitions(-DHAVE_EXECINFO)
160   include_directories(${EXECINFO_INCLUDES})
161   link_libraries(${EXECINFO_LIBRARIES})
162 endif(EXECINFO_FOUND)
163
164 # Select a Qt installation here, if you don't want to use system Qt
165 if(QT)
166   # FindQt4 will look for the qmake binary in $PATH, so we just prepend the Qt dir
167   set(ENV{PATH} ${QT}/bin:$ENV{PATH})
168 endif(QT)
169
170 # Now that we have the correct $PATH, lets find Qt!
171 find_package(Qt4 REQUIRED)
172
173 set(QT_DONT_USE_QTGUI 1)
174 include(${QT_USE_FILE})
175 include_directories(${QT_INCLUDES})
176
177 # PkgConfig isn't strictly required.
178 # However, some optional deps might not be found if it's not present, so warn!
179 find_package(PkgConfig)
180 if(NOT PKG_CONFIG_FOUND)
181   message(STATUS "WARNING: PkgConfig not available! Some dependencies for optional features might not be found.")
182   message(STATUS "         Affected features might include encryption support, DBus menus and Ayatana notifications.")
183 endif(NOT PKG_CONFIG_FOUND)
184
185 # Setup OpenSSL
186 # We don't link to or include OpenSSL ourselves, but use exclusively the Qt API.
187 # Thus, we simply check if OpenSSL support is present in Qt's config and enable our
188 # own SSL stuff in this case. Qt should care for adding what it needs itself.
189 if(WITH_OPENSSL)
190   if(QT_QCONFIG MATCHES "openssl")
191     message(STATUS "Found OpenSSL support in Qt, enabling SSL")
192     add_definitions(-DHAVE_SSL)
193     set(HAVE_SSL true)
194   else(QT_QCONFIG MATCHES "openssl")
195     message(STATUS "No OpenSSL support found in Qt, disabling SSL")
196     add_definitions(-DQT_NO_OPENSSL)
197   endif(QT_QCONFIG MATCHES "openssl")
198 else(WITH_OPENSSL)
199   message(STATUS "Not enabling OpenSSL support")
200 endif(WITH_OPENSSL)
201
202 # Check for GUI specific stuff
203 if(BUILD_GUI)
204
205   # Setup D-Bus support
206   if(WITH_DBUS)
207     if(QT_QTDBUS_FOUND)
208       message(STATUS "Found QtDBus, enabling D-Bus support")
209       add_definitions(-DHAVE_DBUS)
210       set(CLIENT_QT4_VARS ${CLIENT_QT4_VARS} DBUS)
211       set(CLIENT_COMPILE_FLAGS "${CLIENT_COMPILE_FLAGS} -DQT_DBUS_LIB")
212       set(HAVE_DBUS true)
213
214       # check if we have dbusmenu as well
215       find_package(DBusMenuQt)
216       if(DBUSMENUQT_FOUND)
217         message(STATUS "Enabling support for exporting the tray menu via D-Bus")
218         add_definitions(-DHAVE_DBUSMENU)
219         include_directories(${DBUSMENUQT_INCLUDE_DIR})
220         set(CLIENT_LIBRARIES ${CLIENT_LIBRARIES} ${DBUSMENUQT_LIBRARIES})
221         set(CLIENT_COMPILE_FLAGS "${CLIENT_COMPILE_FLAGS} ${DBUSMENUQT_DEFINITIONS}")
222       else(DBUSMENUQT_FOUND)
223         message(STATUS "Disabling support for exporting the tray menu via D-Bus")
224       endif(DBUSMENUQT_FOUND)
225
226     else(QT_QTDBUS_FOUND)
227       message(STATUS "QtDBus not found, disabling D-Bus support")
228     endif(QT_QTDBUS_FOUND)
229   else(WITH_DBUS)
230     message(STATUS "Not enabling D-Bus support")
231   endif(WITH_DBUS)
232
233   # Setup QtWebKit support
234   if(WITH_WEBKIT)
235     if(QT_QTWEBKIT_FOUND)
236       message(STATUS "Found QtWebKit, enabling WebKit support")
237       add_definitions(-DHAVE_WEBKIT)
238       set(CLIENT_QT4_VARS ${CLIENT_QT4_VARS} WEBKIT XMLPATTERNS)
239       set(CLIENT_COMPILE_FLAGS "${CLIENT_COMPILE_FLAGS} -DQT_WEBKIT_LIB -DQT_XMLPATTERNS_LIB")
240       set(HAVE_WEBKIT true)
241     else(QT_QTWEBKIT_FOUND)
242       message(STATUS "QtWebKit not found, disabling WebKit support")
243     endif(QT_QTWEBKIT_FOUND)
244   else(WITH_WEBKIT)
245     message(STATUS "Not enabling WebKit support")
246   endif(WITH_WEBKIT)
247
248   # Setup KDE4 support
249   if(WITH_KDE)
250     find_package(KDE4)
251     if(KDE4_FOUND)
252       message(STATUS "Enabling KDE4 integration")
253       include_directories(${KDE4_INCLUDES})
254       add_definitions(-DHAVE_KDE ${KDE4_DEFINITIONS})
255       set(HAVE_KDE 1)
256       set(CLIENT_LIBRARIES ${CLIENT_LIBRARIES} ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBRARY} ${KDE4_SOLID_LIBS} knotifyconfig)
257       # We always use external icons for KDE4 support, since we use its iconloader rather than our own
258       set(EMBED_DATA OFF)
259     else(KDE4_FOUND)
260       message(STATUS "KDE4 not found, disabling KDE integration")
261     endif(KDE4_FOUND)
262   else(WITH_KDE)
263     message(STATUS "Not enabling KDE4 integration")
264   endif(WITH_KDE)
265
266   # Setup Phonon support - we only need this if we don't have or want KDE4
267   if(NOT HAVE_KDE)
268     if(WITH_PHONON)
269       find_package(Phonon)
270       if(PHONON_FOUND)
271         message(STATUS "Enabling Phonon support")
272         add_definitions(-DHAVE_PHONON)
273         include_directories(${PHONON_INCLUDES})
274         set(CLIENT_LIBRARIES ${CLIENT_LIBRARIES} ${PHONON_LIBS})
275         set(HAVE_PHONON true)
276       else(PHONON_FOUND)
277         message(STATUS "Phonon not found, disabling audio notifications")
278       endif(PHONON_FOUND)
279     else(WITH_PHONON)
280       message(STATUS "Not enabling Phonon support")
281     endif(WITH_PHONON)
282   endif(NOT HAVE_KDE)
283
284   # Setup libindicate-qt support
285   if(WITH_LIBINDICATE)
286     pkg_check_modules(INDICATEQT QUIET indicate-qt>=0.2.1)
287     if(INDICATEQT_FOUND)
288       message(STATUS "Enabling Ayatana notification support")
289       set(HAVE_INDICATEQT true)
290       add_definitions(-DHAVE_INDICATEQT)
291       link_directories(${INDICATEQT_LIBRARY_DIRS})
292       set(CLIENT_LIBRARIES ${CLIENT_LIBRARIES} ${INDICATEQT_LIBRARIES})
293     else(INDICATEQT_FOUND)
294       message(STATUS "Disabling Ayatana notification support")
295     endif(INDICATEQT_FOUND)
296   else(WITH_LIBINDICATE)
297     message(STATUS "Not enabling Ayatana notification support")
298     # We don't want to link against it even if another package has found it
299     set(INDICATEQT_LIBRARIES "")
300   endif(WITH_LIBINDICATE)
301
302 endif(BUILD_GUI)
303
304 # Core-only deps
305 if(BUILD_CORE)
306
307   # Setup encryption support
308   if(WITH_CRYPT)
309     find_package(QCA2)
310     if(QCA2_FOUND)
311       message(STATUS "Found QCA2, enabling encryption support")
312       add_definitions(-DHAVE_QCA2)
313       set(LINK_QCA2 QCA2)
314       set(HAVE_QCA2 true)
315       set(MOC_DEFINES ${MOC_DEFINES} -DHAVE_QCA2)
316     else(QCA2_FOUND)
317       message(STATUS "QCA2 not found, disabling encryption support")
318     endif(QCA2_FOUND)
319   else(WITH_CRYPT)
320     message(STATUS "Not enabling encryption support")
321   endif(WITH_CRYPT)
322
323   # Setup syslog support
324   if(WITH_SYSLOG)
325     check_include_file(syslog.h HAVE_SYSLOG_H)
326     if(HAVE_SYSLOG_H)
327       message(STATUS "Enabling syslog support")
328       set(HAVE_SYSLOG true)
329       add_definitions(-DHAVE_SYSLOG)
330     else(HAVE_SYSLOG_H)
331       message(STATUS "Disabling syslog support")
332     endif(HAVE_SYSLOG_H)
333   else(WITH_SYSLOG)
334     message(STATUS "Not enabling syslog support")
335   endif(WITH_SYSLOG)
336
337 endif(BUILD_CORE)
338
339 # needed to compile with mingw without kde
340 if(MINGW AND NOT HAVE_KDE)
341     add_definitions(-D_WIN32_WINNT=0x0500)
342     message(STATUS "Added _WIN32_WINNT=0x0500 definition for MinGW")
343 # workaround for bug in mingw gcc 4.0
344     add_definitions(-U__STRICT_ANSI__)
345 endif(MINGW AND NOT HAVE_KDE)
346
347 # Now set up install locations; those are set by KDE if integration is enabled
348 if(NOT HAVE_KDE)
349   if(WIN32)
350     set(BIN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX} CACHE FILEPATH "Install path for binaries")
351     set(DATA_INSTALL_DIR $ENV{APPDATA}/quassel-irc.org/share/apps CACHE FILEPATH "Install path for data files")
352     set(ICON_INSTALL_DIR $ENV{APPDATA}/quassel-irc.org/share/icons CACHE FILEPATH "Global icon install path")
353     set(XDG_APPS_INSTALL_DIR $ENV{APPDATA}/quassel-irc.org/share/applications CACHE FILEPATH "Install path for .desktop files")
354   else(WIN32)
355     set(BIN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin CACHE FILEPATH "Install path for binaries")
356     set(DATA_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/apps CACHE FILEPATH "Install path for data files")
357     set(ICON_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/icons CACHE FILEPATH "Global icon install path")
358     set(XDG_APPS_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/applications CACHE FILEPATH "Install path for .desktop files")
359   endif(WIN32)
360 endif(NOT HAVE_KDE)
361
362 if(EMBED_DATA)
363   message(STATUS "Embedding data files into the binary")
364 else(EMBED_DATA)
365   message(STATUS "Installing data files separately")
366 endif(EMBED_DATA)
367
368 # RPATH needs to be set correctly
369 # Do this down here, since otherwise KDE wants to handle it itself, and fails
370 set(CMAKE_INSTALL_RPATH_USE_LINK_PATH 1)
371 set(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
372
373 # Set global buildflags
374 # This is very much non-portable, so don't use -DSTATIC until you know what
375 # you do.
376 if(STATIC AND CMAKE_COMPILER_IS_GNUCXX)
377   set(CMAKE_CXX_FLAGS "-static-libgcc ${CMAKE_CXX_FLAGS}")
378   link_directories(${CMAKE_BINARY_DIR}/staticlibs) # override dynamic libs
379   if(HAVE_SSL)
380     set(QUASSEL_SSL_LIBRARIES ssl crypto)  # these miss in static builds
381   endif(HAVE_SSL)
382 endif(STATIC AND CMAKE_COMPILER_IS_GNUCXX)
383
384 if(WIN32)
385   link_libraries(imm32 winmm dbghelp Secur32)  # missing by default :/
386   if(MSVC)
387     set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBUGINFO "/debug /INCREMENTAL:YES /NODEFAULTLIB:libcmt /DEFAULTLIB:msvcrt")
388     set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBUGINFO}")
389     set(CMAKE_EXE_LINKER_FLAGS_DEBUGFULL "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBUGINFO}")
390     link_libraries(Version dwmapi shlwapi)
391   endif(MSVC)
392   if(HAVE_SSL AND STATIC)
393      find_package(OpenSSL REQUIRED)
394      link_libraries(${OPENSSL_LIBRARIES} ${OPENSSL_EAY_LIBRARIES})
395   endif(HAVE_SSL AND STATIC)
396 endif(WIN32)
397
398 if(HAVE_INDICATEQT)
399   add_definitions(-DXDG_APPS_INSTALL_DIR=${XDG_APPS_INSTALL_DIR})
400 endif(HAVE_INDICATEQT)
401
402 if(NOT WIN32)
403   check_function_exists(umask HAVE_UMASK)
404   if(HAVE_UMASK)
405     add_definitions(-DHAVE_UMASK)
406   endif(HAVE_UMASK)
407 endif(NOT WIN32)
408
409 # We need to create a version.gen
410 # For this, we create our genversion binary and make sure it is run every time.
411 add_executable(genversion ${CMAKE_SOURCE_DIR}/src/common/genversion.cpp)
412 target_link_libraries(genversion ${QT_LIBRARIES} ${QT_CORE_LIB_DEPENDENCIES})
413
414 get_target_property(GENVERSION_EXECUTABLE genversion LOCATION)
415 add_custom_target(genversion_run ALL ${GENVERSION_EXECUTABLE}
416                   ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/src/version.gen)
417 add_dependencies(genversion_run genversion)
418
419 # These variables will be added to the main targets (CORE, QTCLIENT, MONO)
420 set(COMMON_DEPS ${RC_WIN32})
421 set(CORE_DEPS )
422 set(CLIENT_DEPS )
423
424 # Add needed subdirs - the order is important, since src needs some vars set by other dirs
425 add_subdirectory(data)
426 add_subdirectory(icons)
427 add_subdirectory(pics)
428 add_subdirectory(po)
429 add_subdirectory(src)