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