f6b7f65be53d8dd525fa4ca34627dc5ac3a3ea17
[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 3.5)
10
11 # Tell CMake about or own modules
12 set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
13
14 # Versions
15 set(QUASSEL_MAJOR  0)
16 set(QUASSEL_MINOR 13)
17 set(QUASSEL_PATCH 50)
18 set(QUASSEL_VERSION_STRING "0.14-pre")
19
20 # Output CMake and Quassel versions as well as build type for debug reasons
21 message(STATUS "Building Quassel ${QUASSEL_VERSION_STRING}...")
22 message(STATUS "Using CMake ${CMAKE_VERSION}")
23
24 # Set up build type rather early
25 include(BuildType)
26
27 # Support ccache if found
28 # This should happen before calling project(), so compiler settings are validated.
29 option(USE_CCACHE "Enable support for ccache if available" ON)
30 if (USE_CCACHE)
31     message(STATUS "Checking for ccache")
32     find_program(CCACHE_PROGRAM ccache)
33     if (CCACHE_PROGRAM)
34         set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
35         message(STATUS "Checking for ccache - enabled")
36     else()
37         message(STATUS "Checking for ccache - not found")
38     endif()
39 endif()
40
41 # Set up project
42 project(Quassel CXX)
43
44 # Let CMake handle file generation for Qt
45 set(CMAKE_AUTOMOC ON)
46 set(CMAKE_AUTORCC ON)
47 set(CMAKE_AUTOUIC ON)
48
49 # Needed, otherwise some .moc files won't be found with older CMake versions
50 set(CMAKE_INCLUDE_CURRENT_DIR ON)
51
52 # Include various CMake modules...
53 include(CMakePushCheckState)
54 include(CheckFunctionExists)
55 include(CheckIncludeFileCXX)
56 include(CheckCXXSourceCompiles)
57 include(CMakeDependentOption)
58 include(FeatureSummary)
59
60 # ... and our own
61 include(QuasselCompileSettings)
62 include(QuasselMacros)
63
64 # Options and variables that can be set on the command line
65 #####################################################################
66
67 # Select the binaries to build
68 option(WANT_CORE     "Build the core (server) binary"           ON)
69 option(WANT_QTCLIENT "Build the client-only binary"             ON)
70 option(WANT_MONO     "Build the monolithic (all-in-one) binary" ON)
71 add_feature_info(WANT_CORE WANT_CORE "Build the core (server) binary")
72 add_feature_info(WANT_QTCLIENT WANT_QTCLIENT "Build the client-only binary (requires a core to connect to)")
73 add_feature_info(WANT_MONO WANT_MONO "Build the monolithic (all-in-one) binary")
74
75 # Whether to enable integration with higher-tier KDE frameworks that require runtime support.
76 # We still optionally make use of certain Tier 1 frameworks even if WITH_KDE is disabled.
77 option(WITH_KDE "Integration with the KDE Frameworks runtime environment")
78 add_feature_info(WITH_KDE WITH_KDE "Integrate with the KDE Frameworks runtime environment")
79
80 # Icon theme support. By default, install the Breeze icon theme (may be disabled if a system installation is present)
81 option(WITH_BUNDLED_ICONS "Install required icons from the Breeze icon theme" ON)
82 add_feature_info(WITH_BUNDLED_ICONS WITH_BUNDLED_ICONS "Install required icons from the Breeze icon theme")
83
84 option(WITH_OXYGEN_ICONS "Support the Oxygen icon theme (KDE4)" OFF)
85 add_feature_info(WITH_OXYGEN_ICONS WITH_OXYGEN_ICONS "Support the Oxygen icon theme (KDE4)")
86
87 # For this, the feature info is added after we know if QtWebkit is installed
88 option(WITH_WEBKIT "WebKit support (for link previews) (legacy)" OFF)
89
90 # For this, the feature info is added after we know if QtWebEngine is installed
91 option(WITH_WEBENGINE "WebEngine support (for link previews)" ON)
92
93 if (APPLE)
94     # Notification Center is only available in > 10.8, which is Darwin v12
95     if (NOT CMAKE_SYSTEM_VERSION VERSION_LESS 12)
96         option(WITH_NOTIFICATION_CENTER "OS X Notification Center support" ON)
97         add_feature_info(WITH_NOTIFICATION_CENTER WITH_NOTIFICATION_CENTER "Use the OS X Notification Center")
98     endif()
99     find_library(CARBON_LIBRARY Carbon)
100     mark_as_advanced(CARBON_LIBRARY)
101     link_libraries(${CARBON_LIBRARY})
102 endif()
103
104 # Always embed on Windows or OSX; never embed when enabling KDE integration
105 set(EMBED_DEFAULT OFF)
106 if (WIN32 OR APPLE)
107     set(EMBED_DEFAULT ON)
108 endif()
109 cmake_dependent_option(EMBED_DATA "Embed icons and translations into the binaries instead of installing them" ${EMBED_DEFAULT}
110                                    "NOT WIN32;NOT WITH_KDE" ${EMBED_DEFAULT})
111 if (NOT EMBED_DEFAULT)
112     add_feature_info(EMBED_DATA EMBED_DATA "Embed icons and translations in the binaries instead of installing them")
113 endif()
114
115 # The following options are not for end-user consumption, so don't list them in the feature summary
116 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)
117
118
119 # List of authenticators and the cmake flags to build them
120 # (currently that's just LDAP, but more can be added here).
121 ####################################################################
122 option(WITH_LDAP "Enable LDAP authentication support if present on system" ON)
123
124 # Setup CMake
125 #####################################################################
126
127 # Let automoc/autouic process generated files
128 if (POLICY CMP0071)
129     cmake_policy(SET CMP0071 NEW)
130 endif()
131
132 # Simplify later checks
133 #####################################################################
134
135 if (WANT_MONO OR WANT_QTCLIENT)
136     set(BUILD_GUI true)
137 endif()
138 if (WANT_MONO OR WANT_CORE)
139     set(BUILD_CORE true)
140 endif()
141
142
143 # Set up Qt
144 #####################################################################
145
146 # Find package dependencies
147 #
148 # Note that you can forcefully disable optional packages
149 # using -DCMAKE_DISABLE_FIND_PACKAGE_<PkgName>=TRUE
150 #####################################################################
151
152 set(QT_MIN_VERSION "5.5.0")
153
154 # Required Qt components
155 set(qt_components Core Network)
156 if (BUILD_GUI)
157     list(APPEND qt_components Gui Widgets)
158 endif()
159 if (BUILD_CORE)
160     list(APPEND qt_components Script Sql)
161 endif()
162
163 find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS ${qt_components})
164 set_package_properties(Qt5 PROPERTIES TYPE REQUIRED
165     URL "https://www.qt.io/"
166     DESCRIPTION "the Qt libraries"
167 )
168 message(STATUS "Found Qt ${Qt5Core_VERSION}")
169
170 # Optional Qt components
171
172 find_package(Qt5LinguistTools QUIET)
173 set_package_properties(Qt5LinguistTools PROPERTIES TYPE RECOMMENDED
174     DESCRIPTION "contains tools for handling translation files"
175     PURPOSE "Required for having translations"
176 )
177
178 if (BUILD_GUI)
179     if (NOT WIN32)
180         find_package(Qt5DBus QUIET)
181         set_package_properties(Qt5DBus PROPERTIES TYPE RECOMMENDED
182             URL "https://www.qt.io/"
183             DESCRIPTION "D-Bus support for Qt5"
184             PURPOSE     "Needed for supporting D-Bus-based notifications and tray icon, used by most modern desktop environments"
185         )
186         if (Qt5DBus_FOUND)
187             find_package(dbusmenu-qt5 QUIET CONFIG)
188             set_package_properties(dbusmenu-qt5 PROPERTIES TYPE RECOMMENDED
189                 URL "https://launchpad.net/libdbusmenu-qt"
190                 DESCRIPTION "a library implementing the DBusMenu specification"
191                 PURPOSE     "Required for having a context menu for the D-Bus-based tray icon"
192             )
193         endif()
194     endif()
195
196     find_package(Qt5Multimedia QUIET)
197     set_package_properties(Qt5Multimedia PROPERTIES TYPE RECOMMENDED
198         URL "https://www.qt.io/"
199         DESCRIPTION "Multimedia support for Qt5"
200         PURPOSE     "Required for audio notifications"
201     )
202
203     find_package(LibsnoreQt5 0.7.0 QUIET)
204     set_package_properties(LibsnoreQt5 PROPERTIES TYPE OPTIONAL
205         URL "https://projects.kde.org/projects/playground/libs/snorenotify"
206         DESCRIPTION "a cross-platform notification framework"
207         PURPOSE     "Enable support for the snorenotify framework"
208     )
209     if (LibsnoreQt5_FOUND)
210         find_package(LibsnoreSettingsQt5 QUIET)
211         set_package_properties(LibsnoreSettingsQt5 PROPERTIES TYPE OPTIONAL
212             URL "https://projects.kde.org/projects/playground/libs/snorenotify"
213             DESCRIPTION "a cross-platform notification framework"
214             PURPOSE     "Enable support for the snorenotify framework"
215         )
216     endif()
217
218     if (WITH_WEBENGINE)
219         find_package(Qt5WebEngine QUIET)
220         set_package_properties(Qt5WebEngine PROPERTIES TYPE RECOMMENDED
221             URL "https://www.qt.io/"
222             DESCRIPTION "a WebEngine implementation for Qt"
223             PURPOSE     "Needed for displaying previews for URLs in chat"
224         )
225         if (Qt5WebEngine_FOUND)
226             find_package(Qt5WebEngineWidgets QUIET)
227             set_package_properties(Qt5WebEngineWidgets PROPERTIES TYPE RECOMMENDED
228                 URL "https://www.qt.io/"
229                 DESCRIPTION "widgets for Qt's WebEngine implementation"
230                 PURPOSE     "Needed for displaying previews for URLs in chat"
231             )
232         endif()
233     endif()
234
235     if (WITH_WEBENGINE AND Qt5WebEngineWidgets_FOUND)
236         set(HAVE_WEBENGINE true)
237     endif()
238     add_feature_info("WITH_WEBENGINE, QtWebEngine and QtWebEngineWidgets modules" HAVE_WEBENGINE "Support showing previews for URLs in chat")
239
240     if (NOT HAVE_WEBENGINE)
241         if (WITH_WEBKIT)
242             find_package(Qt5WebKit QUIET)
243             set_package_properties(Qt5WebKit PROPERTIES TYPE OPTIONAL
244                 URL "https://www.qt.io/"
245                 DESCRIPTION "a WebKit implementation for Qt"
246                 PURPOSE     "Needed for displaying previews for URLs in chat"
247                 )
248             if (Qt5WebKit_FOUND)
249                 find_package(Qt5WebKitWidgets QUIET)
250                 set_package_properties(Qt5WebKitWidgets PROPERTIES TYPE OPTIONAL
251                     URL "https://www.qt.io/"
252                     DESCRIPTION "widgets for Qt's WebKit implementation"
253                     PURPOSE     "Needed for displaying previews for URLs in chat"
254                     )
255             endif()
256         endif()
257
258         if (WITH_WEBKIT AND Qt5WebKitWidgets_FOUND)
259             set(HAVE_WEBKIT true)
260         endif()
261         add_feature_info("WITH_WEBKIT, QtWebKit and QtWebKitWidgets modules" HAVE_WEBKIT "Support showing previews for URLs in chat (legacy)")
262     endif()
263
264     # KDE Frameworks
265     ################
266
267     # extra-cmake-modules
268     if (WITH_KDE)
269         set(ecm_find_type "REQUIRED")
270         find_package(ECM NO_MODULE REQUIRED)
271     else()
272         # Even with KDE integration disabled, we optionally use tier1 frameworks if we find them
273         set(ecm_find_type "RECOMMENDED")
274         find_package(ECM NO_MODULE QUIET)
275     endif()
276
277     set_package_properties(ECM PROPERTIES TYPE ${ecm_find_type}
278         URL "https://projects.kde.org/projects/kdesupport/extra-cmake-modules"
279         DESCRIPTION "extra modules for CMake, maintained by the KDE project"
280         PURPOSE     "Required to find KDE Frameworks components"
281     )
282
283     if (ECM_FOUND)
284         list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
285         if (WITH_KDE)
286             find_package(KF5 REQUIRED COMPONENTS ConfigWidgets CoreAddons Notifications NotifyConfig Sonnet TextWidgets WidgetsAddons XmlGui)
287             set_package_properties(KF5 PROPERTIES TYPE REQUIRED
288                 URL "http://www.kde.org"
289                 DESCRIPTION "KDE Frameworks"
290                 PURPOSE     "Required for integration into the Plasma desktop"
291             )
292             message(STATUS "Found KDE Frameworks ${KF5_VERSION}")
293         endif()
294
295         # Optional KF5 tier1 components
296         find_package(KF5Sonnet QUIET)
297         set_package_properties(KF5Sonnet PROPERTIES TYPE RECOMMENDED
298             URL "http://api.kde.org/frameworks-api/frameworks5-apidocs/sonnet/html"
299             DESCRIPTION "framework for providing spell-checking capabilities"
300             PURPOSE "Enables spell-checking support in input widgets"
301         )
302     endif()
303 endif()
304
305 if (BUILD_CORE)
306     find_package(Qca-qt5 2.0 QUIET)
307     set_package_properties(Qca-qt5 PROPERTIES TYPE RECOMMENDED
308         URL "https://projects.kde.org/projects/kdesupport/qca"
309         DESCRIPTION "Qt Cryptographic Architecture"
310         PURPOSE "Required for encryption support"
311     )
312
313     if (WITH_LDAP)
314         find_package(Ldap QUIET)
315         if (LDAP_FOUND)
316             message(STATUS "Enabling LDAP authentication support")
317         else()
318             message(STATUS "Disabling LDAP authentication support")
319         endif()
320     else()
321         message(STATUS "Not enabling LDAP authentication support")
322     endif()
323 endif()
324
325 # Non-Qt-based packages
326
327 find_package(ZLIB REQUIRED)
328 set_package_properties(ZLIB PROPERTIES TYPE REQUIRED
329     URL "http://www.zlib.net"
330     DESCRIPTION "a popular compression library"
331     PURPOSE     "Used for protocol compression"
332 )
333
334 if (NOT WIN32)
335     # Needed for generating backtraces
336     find_package(Backtrace QUIET)
337     set_package_properties(Backtrace PROPERTIES TYPE RECOMMENDED
338         DESCRIPTION "a header (and possibly library) for inspecting backtraces"
339         PURPOSE "Used for generating backtraces in case of a crash"
340     )
341 endif()
342
343 # Check for SSL support in Qt
344 cmake_push_check_state(RESET)
345 set(CMAKE_REQUIRED_LIBRARIES Qt5::Core)
346 check_cxx_source_compiles("
347     #include \"qglobal.h\"
348     #if defined QT_NO_SSL
349     #  error \"No SSL support\"
350     #endif
351     int main() {}"
352     HAVE_SSL)
353 cmake_pop_check_state()
354
355 if (HAVE_SSL)
356     add_definitions(-DHAVE_SSL)
357 endif()
358 add_feature_info("SSL support in Qt" HAVE_SSL "Use secure network connections")
359
360 # Additional compile settings
361 #####################################################################
362
363 # Needed to compile with mingw without kde
364 if (MINGW AND NOT WITH_KDE)
365     add_definitions(-D_WIN32_WINNT=0x0500)
366     message(STATUS "Added _WIN32_WINNT=0x0500 definition for MinGW")
367     # workaround for bug in mingw gcc 4.0
368     add_definitions(-U__STRICT_ANSI__)
369 endif()
370
371 # Setup support for KDE Frameworks
372 #####################################################################
373
374 # We want to do this up here, so we have the necessary variables and defines set before
375 # compiling anything
376
377 if (WITH_KDE)
378     # If KDE Frameworks are present, they're most probably providing Qt5 integration including icon loading
379     set(EMBED_DATA OFF)
380
381     include(KDEInstallDirs)
382     include(KDECompilerSettings)
383     include(KDECMakeSettings)
384
385     kde_enable_exceptions()
386     add_definitions(-DHAVE_KDE -DHAVE_KF5)
387     set(WITH_KF5 TRUE)
388 endif()
389
390 # This needs to come after setting up KDE integration, so we can use KDE-specific paths
391 include(QuasselInstallDirs)
392
393 # Various config-dependent checks and settings
394 #####################################################################
395
396 # Check for syslog support
397 if (NOT WIN32)
398     check_include_file_cxx(syslog.h HAVE_SYSLOG)
399     add_feature_info("syslog.h" HAVE_SYSLOG "Provide support for logging to the syslog")
400 endif()
401
402 if (NOT WIN32)
403     check_function_exists(umask HAVE_UMASK)
404 endif()
405
406 if (EMBED_DATA)
407     message(STATUS "Embedding data files into the binary")
408 else()
409     message(STATUS "Installing data files separately")
410 endif()
411
412 # Windows-specific stuff
413 #####################################################################
414
415 if (WIN32)
416     link_libraries(imm32 winmm dbghelp Secur32)  # missing by default :/
417     if (MSVC)
418         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /DNOMINMAX")
419         set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBUGINFO "/debug /INCREMENTAL:YES /NODEFAULTLIB:libcmt /DEFAULTLIB:msvcrt")
420         set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/debug /INCREMENTAL:YES /NODEFAULTLIB:libcmt")
421         set(CMAKE_EXE_LINKER_FLAGS_DEBUGFULL "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
422         link_libraries(Version dwmapi shlwapi)
423     endif()
424 endif()
425
426
427 # Generate version information from Git
428 #####################################################################
429
430 include(GetGitRevisionDescription)
431 get_git_head_revision(GIT_REFSPEC GIT_HEAD)
432 git_describe(GIT_DESCRIBE --long)
433
434 # If in a Git repo we can get the commit-date from a git command
435 if (GIT_HEAD)
436     execute_process(
437         COMMAND git -c log.showsignature=false show -s --format=%ct
438         WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
439         OUTPUT_VARIABLE GIT_COMMIT_DATE
440         OUTPUT_STRIP_TRAILING_WHITESPACE
441     )
442 endif()
443
444 # If not in a Git repo try to read GIT_HEAD and GIT_DESCRIBE from
445 # enviroment
446 if (NOT GIT_HEAD OR NOT GIT_DESCRIBE)
447   if (DEFINED ENV{GIT_HEAD})
448       set(GIT_HEAD $ENV{GIT_HEAD})
449   endif()
450   if (DEFINED ENV{GIT_DESCRIBE})
451      set(GIT_DESCRIBE $ENV{GIT_DESCRIBE})
452   endif()
453 endif()
454
455 # Sanitize things if we're not in a Git repo
456 if (NOT GIT_HEAD OR NOT GIT_DESCRIBE)
457     set(GIT_HEAD "")
458     set(GIT_DESCRIBE "")
459     set(GIT_COMMIT_DATE 0)
460 endif()
461
462 configure_file(version.h.in ${CMAKE_BINARY_DIR}/version.h @ONLY)
463
464 # Prepare the build
465 #####################################################################
466
467 # Add needed subdirs - the order is important, since src needs some vars set by other dirs
468 add_subdirectory(data)
469 add_subdirectory(icons)
470 add_subdirectory(pics)
471 add_subdirectory(po)
472
473
474 # Set up and display feature summary
475 #####################################################################
476
477 feature_summary(WHAT ALL
478                 INCLUDE_QUIET_PACKAGES
479                 FATAL_ON_MISSING_REQUIRED_PACKAGES
480 )
481
482 # Finally, compile the sources
483 # We want this after displaying the feature summary to avoid ugly
484 # CMake backtraces in case a required Qt5 module is missing
485 #####################################################################
486
487 add_subdirectory(src)