2 # Copyright (C) 2004-2018 ZNC, see the NOTICE file for details.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 cmake_minimum_required(VERSION 3.1)
18 project(ZNC VERSION 1.7.4)
19 set(ZNC_VERSION 1.7.4)
20 set(append_git_version false)
21 set(alpha_version "") # e.g. "-rc1"
22 set(VERSION_EXTRA "" CACHE STRING
23 "Additional string appended to version, e.g. to mark distribution")
25 set(PROJECT_VERSION "${ZNC_VERSION}")
27 # https://cmake.org/pipermail/cmake/2010-September/039388.html
28 set(_all_targets "" CACHE INTERNAL "")
29 function(znc_add_library name)
30 add_library("${name}" ${ARGN})
31 set(_all_targets "${_all_targets};${name}" CACHE INTERNAL "")
33 function(znc_add_executable name)
34 add_executable("${name}" ${ARGN})
35 set(_all_targets "${_all_targets};${name}" CACHE INTERNAL "")
37 function(znc_add_custom_target name)
38 add_custom_target("${name}" ${ARGN})
39 set(_all_targets "${_all_targets};${name}" CACHE INTERNAL "")
42 list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
45 set(CMAKE_CXX_STANDARD 11)
46 set(CMAKE_CXX_STANDARD_REQUIRED true)
48 # We don't want to use -std=gnu++11 instead of -std=c++11, but among other
49 # things, -std=c++11 on cygwin defines __STRICT_ANSI__ which makes cygwin
50 # not to compile: undefined references to strerror_r, to fdopen, to
51 # strcasecmp, etc (their declarations in system headers are between ifdef)
52 set(CMAKE_CXX_EXTENSIONS false)
55 include(CMakeFindFrameworks_fixed)
57 include(GNUInstallDirs)
58 include(CheckCXXSymbolExists)
61 set(CMAKE_THREAD_PREFER_PTHREAD true)
62 set(THREADS_PREFER_PTHREAD_FLAG true)
63 find_package(Threads REQUIRED)
64 if(NOT CMAKE_USE_PTHREADS_INIT)
65 message(FATAL_ERROR "This compiler/OS doesn't seem to support pthreads.")
68 include(TestLargeFiles)
69 test_large_files(HAVE_LARGE_FILES_UNUSED_VAR)
70 find_package(PkgConfig)
72 macro(tristate_option opt help)
73 set(WANT_${opt} AUTO CACHE STRING ${help})
74 set_property(CACHE WANT_${opt} PROPERTY STRINGS AUTO YES NO)
75 if(WANT_${opt} STREQUAL "AUTO")
76 set(TRISTATE_${opt}_REQUIRED)
78 set(TRISTATE_${opt}_REQUIRED REQUIRED)
82 tristate_option(OPENSSL "Support SSL")
84 find_package(OpenSSL ${TRISTATE_OPENSSL_REQUIRED})
86 set(HAVE_LIBSSL "${OPENSSL_FOUND}")
88 set(WANT_IPV6 true CACHE BOOL "Support IPv6")
89 set(HAVE_IPV6 "${WANT_IPV6}")
91 tristate_option(ZLIB "Compress HTTP traffic with Zlib")
93 find_package(ZLIB ${TRISTATE_ZLIB_REQUIRED})
95 set(HAVE_ZLIB "${ZLIB_FOUND}")
97 tristate_option(CYRUS "Support authentication with Cyrus")
99 pkg_check_modules(CYRUS libsasl2)
101 # libsasl2.pc is missing on 2.1.25 which is on ubuntu 14.04
102 # next ubuntu version has 2.1.26 which has libsasl2.pc
104 # osx (as of El Capitan) doesn't have it either...
105 set(_old_cmake_required_libraries "${CMAKE_REQUIRED_LIBRARIES}")
106 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} -lsasl2)
107 # sys/types.h here is workaround for sasl 2.1.26:
108 # https://github.com/znc/znc/issues/1243
109 # https://lists.andrew.cmu.edu/pipermail/cyrus-sasl/2012-December/002572.html
110 # https://cgit.cyrus.foundation/cyrus-sasl/commit/include/sasl.h?id=2f740223fa1820dd71e6ab0e50d4964760789209
111 check_cxx_symbol_exists(sasl_server_init "sys/types.h;sasl/sasl.h"
113 set(CMAKE_REQUIRED_LIBRARIES "${_old_cmake_required_libraries}")
115 set(CYRUS_LDFLAGS -lsasl2)
116 set(CYRUS_FOUND true)
119 if(TRISTATE_CYRUS_REQUIRED AND NOT CYRUS_FOUND)
120 message(FATAL_ERROR "Can't find Cyrus SASL 2")
124 tristate_option(ICU "Support character encodings")
126 pkg_check_modules(ICU ${TRISTATE_ICU_REQUIRED} icu-uc)
128 set(HAVE_ICU "${ICU_FOUND}")
130 set(WANT_PERL false CACHE BOOL "Support Perl modules")
131 set(WANT_PYTHON false CACHE BOOL "Support Python modules")
132 set(WANT_PYTHON_VERSION "python3" CACHE STRING
133 "Python version to use, e.g. python-3.5, this name is passed to pkg-config")
134 if(WANT_PYTHON AND NOT ICU_FOUND)
135 message(FATAL_ERROR "Modpython requires ZNC to be compiled with charset "
136 "support, but ICU library not found")
138 tristate_option(SWIG "Use SWIG to generate modperl and modpython")
139 set(search_swig false)
140 if(WANT_SWIG AND TRISTATE_SWIG_REQUIRED)
141 set(search_swig true)
143 if(WANT_PERL AND NOT EXISTS
144 "${PROJECT_SOURCE_DIR}/modules/modperl/generated.tar.gz")
146 set(search_swig true)
148 message(FATAL_ERROR "Pregenerated modperl files are not available. "
149 "SWIG is required. Alternatively, build ZNC from tarball.")
152 if(WANT_PYTHON AND NOT EXISTS
153 "${PROJECT_SOURCE_DIR}/modules/modpython/generated.tar.gz")
155 set(search_swig true)
157 message(FATAL_ERROR "Pregenerated modpython files are not available. "
158 "SWIG is required. Alternatively, build ZNC from tarball.")
162 find_package(SWIG 3.0.0)
165 "Can't find SWIG, therefore Perl and Python aren't supported. "
166 "Alternatively, build ZNC from tarball.")
171 find_package(PerlLibs 5.10 REQUIRED)
174 find_package(Perl 5.10 REQUIRED)
175 pkg_check_modules(PYTHON "${WANT_PYTHON_VERSION}" REQUIRED)
178 set(WANT_TCL false CACHE BOOL "Support Tcl modules")
180 find_package(TCL QUIET)
182 message(FATAL_ERROR "Can't find Tcl")
186 tristate_option(I18N "Native language support (i18n)")
188 find_package(Boost ${TRISTATE_I18N_REQUIRED} COMPONENTS locale)
189 find_package(Gettext ${TRISTATE_I18N_REQUIRED})
191 if(Boost_LOCALE_FOUND AND GETTEXT_MSGFMT_EXECUTABLE)
195 message(STATUS "Boost.Locale or gettext (msgfmt) is not found, disabling i18n support")
198 if(HAVE_I18N AND GETTEXT_MSGMERGE_EXECUTABLE)
199 find_program(XGETTEXT_EXECUTABLE xgettext)
200 if(XGETTEXT_EXECUTABLE)
201 add_custom_target(translation)
205 # poll() is broken on Mac OS, it fails with POLLNVAL for pipe()s.
207 set(CSOCK_USE_POLL false)
209 set(CSOCK_USE_POLL true)
212 check_cxx_symbol_exists(getopt_long "getopt.h" HAVE_GETOPT_LONG)
213 check_cxx_symbol_exists(lstat "sys/types.h;sys/stat.h;unistd.h" HAVE_LSTAT)
214 check_cxx_symbol_exists(getpassphrase "stdlib.h" HAVE_GETPASSPHRASE)
215 check_cxx_symbol_exists(tcsetattr "termios.h;unistd.h" HAVE_TCSETATTR)
216 check_cxx_symbol_exists(clock_gettime "time.h" HAVE_CLOCK_GETTIME)
218 # Note that old broken systems, such as OpenBSD, NetBSD, which don't support
219 # AI_ADDRCONFIG, also have thread-unsafe getaddrinfo(). Gladly, they fixed
220 # thread-safety before support of AI_ADDRCONFIG, so this can be abused to
221 # detect the thread-safe getaddrinfo().
223 # TODO: drop support of blocking DNS at some point. OpenBSD supports
224 # AI_ADDRCONFIG since Nov 2014, and their getaddrinfo() is thread-safe since
225 # Nov 2013. NetBSD's one is thread-safe since ages ago.
226 check_cxx_symbol_exists(AI_ADDRCONFIG "sys/types.h;sys/socket.h;netdb.h"
229 if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT CYGWIN)
230 # These enable some debug options in g++'s STL, e.g. invalid use of
231 # iterators, but they cause crashes on cygwin while loading modules
232 set(_GLIBCXX_DEBUG true)
233 set(_GLIBCXX_DEBUG_PEDANTIC true)
236 if(append_git_version)
242 file(GLOB csocket_files LIST_DIRECTORIES FALSE
243 "${PROJECT_SOURCE_DIR}/third_party/Csocket/Csocket.*")
244 if(csocket_files STREQUAL "")
245 execute_process(COMMAND git status
246 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
247 RESULT_VARIABLE git_status_var
252 " It looks like git submodules are not initialized.\n"
253 " Either this is not a git clone, or you don't have git installed")
256 " It looks like git submodules are not initialized.\n"
257 " Run: git submodule update --init --recursive")
261 install(DIRECTORY webskins
262 DESTINATION "${CMAKE_INSTALL_DATADIR}/znc")
263 install(DIRECTORY translations
264 DESTINATION "${CMAKE_INSTALL_DATADIR}/znc")
265 install(DIRECTORY man/
266 DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
267 FILES_MATCHING PATTERN "znc*")
269 set(WANT_SYSTEMD false CACHE BOOL "Install znc.service to systemd")
271 configure_file("znc.service.in" "znc.service")
272 set(SYSTEMD_DIR "" CACHE PATH "Path to systemd units")
273 if(SYSTEMD_DIR STREQUAL "" AND PKG_CONFIG_EXECUTABLE)
274 execute_process(COMMAND "${PKG_CONFIG_EXECUTABLE}"
275 --variable=systemdsystemunitdir systemd
276 OUTPUT_VARIABLE SYSTEMD_DIR)
278 if(SYSTEMD_DIR STREQUAL "")
279 message(FATAL_ERROR "Systemd is enabled, "
280 "but the unit dir can't be found.")
282 install(FILES "${PROJECT_BINARY_DIR}/znc.service"
283 DESTINATION "${SYSTEMD_DIR}")
286 # On cygwin, if to link modules against znc.exe directly, modperl can't call
287 # ZNC's functions very well. They do get called, but global variables have
288 # different addresses. That address actually is in modperl/ZNC.dll if to look
290 # Example of such global variable is one returned by CZNC::Get()
291 # Modpython seems to work though with STATIC on cygwin... (I didn't test it
294 # Non-cygwin should link modules to /usr/bin/znc directly to prevent this:
295 # error while loading shared libraries: libznc.so: cannot open shared object file: No such file or directory
296 # Without need to touch LD_LIBRARY_PATH
298 set(znc_link "znclib")
299 set(lib_type "SHARED")
300 set(install_lib "znclib")
301 set(znclib_pc "-L${CMAKE_INSTALL_FULL_LIBDIR} -lznc")
304 set(lib_type "STATIC")
309 configure_file("include/znc/zncconfig.h.cmake.in" "include/znc/zncconfig.h")
310 add_subdirectory(include)
311 add_subdirectory(src)
312 add_subdirectory(modules)
313 add_subdirectory(test)
314 add_subdirectory(zz_msg)
316 add_custom_target(msg_after_all ALL
317 COMMAND "${CMAKE_COMMAND}" -E echo
318 COMMAND "${CMAKE_COMMAND}" -E echo " ZNC was successfully compiled."
319 COMMAND "${CMAKE_COMMAND}" -E echo
320 " Use 'make install' to install ZNC to '${CMAKE_INSTALL_PREFIX}'."
321 COMMAND "${CMAKE_COMMAND}" -E echo
323 add_dependencies(msg_after_all ${_all_targets})
325 # @echo " ZNC was successfully compiled."
326 # @echo " Use '$(MAKE) install' to install ZNC to '$(prefix)'."
329 configure_file("ZNCConfig.cmake.in" "ZNCConfig.cmake" @ONLY)
330 include(CMakePackageConfigHelpers)
331 write_basic_package_version_file("ZNCConfigVersion.cmake"
332 COMPATIBILITY AnyNewerVersion)
334 "${PROJECT_BINARY_DIR}/ZNCConfig.cmake"
335 "${PROJECT_BINARY_DIR}/ZNCConfigVersion.cmake"
336 DESTINATION "${CMAKE_INSTALL_DATADIR}/znc/cmake")
337 configure_file("znc-buildmod.cmake.in" "znc-buildmod" @ONLY)
338 install(PROGRAMS "${PROJECT_BINARY_DIR}/znc-buildmod"
339 DESTINATION "${CMAKE_INSTALL_BINDIR}")
341 configure_file("znc.pc.cmake.in" "znc.pc" @ONLY)
342 install(FILES "${PROJECT_BINARY_DIR}/znc.pc"
343 DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
345 macro(summary_line text var)
347 list(APPEND summary_lines "${text} : yes")
349 list(APPEND summary_lines "${text} : no")
353 "ZNC ${ZNC_VERSION}${VERSION_EXTRA}${alpha_version} configured"
355 "Prefix : ${CMAKE_INSTALL_PREFIX}")
356 summary_line("SSL " "${OPENSSL_FOUND}")
357 summary_line("IPv6 " "${WANT_IPV6}")
358 summary_line("Async DNS" "${HAVE_THREADED_DNS}")
359 summary_line("Perl " "${PERLLIBS_FOUND}")
360 summary_line("Python " "${PYTHON_FOUND}")
361 summary_line("Tcl " "${TCL_FOUND}")
362 summary_line("Cyrus " "${CYRUS_FOUND}")
363 summary_line("Charset " "${ICU_FOUND}")
364 summary_line("Zlib " "${ZLIB_FOUND}")
365 summary_line("i18n " "${HAVE_I18N}")
367 include(render_framed_multiline)
368 render_framed_multiline("${summary_lines}")
371 message("Now you can run 'make' to compile ZNC")
377 # remove old configure.ac and Makefile.in