]> jfr.im git - irc/znc/znc.git/blob - CMakeLists.txt
ZNC 1.7.4
[irc/znc/znc.git] / CMakeLists.txt
1 #
2 # Copyright (C) 2004-2018 ZNC, see the NOTICE file for details.
3 #
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
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15 #
16
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")
24
25 set(PROJECT_VERSION "${ZNC_VERSION}")
26
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 "")
32 endfunction()
33 function(znc_add_executable name)
34 add_executable("${name}" ${ARGN})
35 set(_all_targets "${_all_targets};${name}" CACHE INTERNAL "")
36 endfunction()
37 function(znc_add_custom_target name)
38 add_custom_target("${name}" ${ARGN})
39 set(_all_targets "${_all_targets};${name}" CACHE INTERNAL "")
40 endfunction()
41
42 list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
43
44 include(TestCXX11)
45 set(CMAKE_CXX_STANDARD 11)
46 set(CMAKE_CXX_STANDARD_REQUIRED true)
47 if(NOT CYGWIN)
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)
53 endif()
54
55 include(CMakeFindFrameworks_fixed)
56 include(use_homebrew)
57 include(GNUInstallDirs)
58 include(CheckCXXSymbolExists)
59 include(copy_csocket)
60
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.")
66 endif()
67
68 include(TestLargeFiles)
69 test_large_files(HAVE_LARGE_FILES_UNUSED_VAR)
70 find_package(PkgConfig)
71
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)
77 else()
78 set(TRISTATE_${opt}_REQUIRED REQUIRED)
79 endif()
80 endmacro()
81
82 tristate_option(OPENSSL "Support SSL")
83 if(WANT_OPENSSL)
84 find_package(OpenSSL ${TRISTATE_OPENSSL_REQUIRED})
85 endif()
86 set(HAVE_LIBSSL "${OPENSSL_FOUND}")
87
88 set(WANT_IPV6 true CACHE BOOL "Support IPv6")
89 set(HAVE_IPV6 "${WANT_IPV6}")
90
91 tristate_option(ZLIB "Compress HTTP traffic with Zlib")
92 if(WANT_ZLIB)
93 find_package(ZLIB ${TRISTATE_ZLIB_REQUIRED})
94 endif()
95 set(HAVE_ZLIB "${ZLIB_FOUND}")
96
97 tristate_option(CYRUS "Support authentication with Cyrus")
98 if(WANT_CYRUS)
99 pkg_check_modules(CYRUS libsasl2)
100 if(NOT CYRUS_FOUND)
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
103 #
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"
112 CYRUS_HARDCODED)
113 set(CMAKE_REQUIRED_LIBRARIES "${_old_cmake_required_libraries}")
114 if(CYRUS_HARDCODED)
115 set(CYRUS_LDFLAGS -lsasl2)
116 set(CYRUS_FOUND true)
117 endif()
118 endif()
119 if(TRISTATE_CYRUS_REQUIRED AND NOT CYRUS_FOUND)
120 message(FATAL_ERROR "Can't find Cyrus SASL 2")
121 endif()
122 endif()
123
124 tristate_option(ICU "Support character encodings")
125 if(WANT_ICU)
126 pkg_check_modules(ICU ${TRISTATE_ICU_REQUIRED} icu-uc)
127 endif()
128 set(HAVE_ICU "${ICU_FOUND}")
129
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")
137 endif()
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)
142 endif()
143 if(WANT_PERL AND NOT EXISTS
144 "${PROJECT_SOURCE_DIR}/modules/modperl/generated.tar.gz")
145 if(WANT_SWIG)
146 set(search_swig true)
147 else()
148 message(FATAL_ERROR "Pregenerated modperl files are not available. "
149 "SWIG is required. Alternatively, build ZNC from tarball.")
150 endif()
151 endif()
152 if(WANT_PYTHON AND NOT EXISTS
153 "${PROJECT_SOURCE_DIR}/modules/modpython/generated.tar.gz")
154 if(WANT_SWIG)
155 set(search_swig true)
156 else()
157 message(FATAL_ERROR "Pregenerated modpython files are not available. "
158 "SWIG is required. Alternatively, build ZNC from tarball.")
159 endif()
160 endif()
161 if(search_swig)
162 find_package(SWIG 3.0.0)
163 if(NOT SWIG_FOUND)
164 message(FATAL_ERROR
165 "Can't find SWIG, therefore Perl and Python aren't supported. "
166 "Alternatively, build ZNC from tarball.")
167 endif()
168 endif()
169
170 if(WANT_PERL)
171 find_package(PerlLibs 5.10 REQUIRED)
172 endif()
173 if (WANT_PYTHON)
174 find_package(Perl 5.10 REQUIRED)
175 pkg_check_modules(PYTHON "${WANT_PYTHON_VERSION}" REQUIRED)
176 endif()
177
178 set(WANT_TCL false CACHE BOOL "Support Tcl modules")
179 if(WANT_TCL)
180 find_package(TCL QUIET)
181 if(NOT TCL_FOUND)
182 message(FATAL_ERROR "Can't find Tcl")
183 endif()
184 endif()
185
186 tristate_option(I18N "Native language support (i18n)")
187 if(WANT_I18N)
188 find_package(Boost ${TRISTATE_I18N_REQUIRED} COMPONENTS locale)
189 find_package(Gettext ${TRISTATE_I18N_REQUIRED})
190 endif()
191 if(Boost_LOCALE_FOUND AND GETTEXT_MSGFMT_EXECUTABLE)
192 set(HAVE_I18N true)
193 else()
194 set(HAVE_I18N false)
195 message(STATUS "Boost.Locale or gettext (msgfmt) is not found, disabling i18n support")
196 endif()
197
198 if(HAVE_I18N AND GETTEXT_MSGMERGE_EXECUTABLE)
199 find_program(XGETTEXT_EXECUTABLE xgettext)
200 if(XGETTEXT_EXECUTABLE)
201 add_custom_target(translation)
202 endif()
203 endif()
204
205 # poll() is broken on Mac OS, it fails with POLLNVAL for pipe()s.
206 if(APPLE)
207 set(CSOCK_USE_POLL false)
208 else()
209 set(CSOCK_USE_POLL true)
210 endif()
211
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)
217
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().
222 #
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"
227 HAVE_THREADED_DNS)
228
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)
234 endif()
235
236 if(append_git_version)
237 find_package(Git)
238 endif()
239
240
241
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
248 OUTPUT_QUIET
249 ERROR_QUIET)
250 if(git_status_var)
251 message(FATAL_ERROR
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")
254 else()
255 message(FATAL_ERROR
256 " It looks like git submodules are not initialized.\n"
257 " Run: git submodule update --init --recursive")
258 endif()
259 endif()
260
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*")
268
269 set(WANT_SYSTEMD false CACHE BOOL "Install znc.service to systemd")
270 if(WANT_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)
277 endif()
278 if(SYSTEMD_DIR STREQUAL "")
279 message(FATAL_ERROR "Systemd is enabled, "
280 "but the unit dir can't be found.")
281 endif()
282 install(FILES "${PROJECT_BINARY_DIR}/znc.service"
283 DESTINATION "${SYSTEMD_DIR}")
284 endif()
285
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
289 # at /proc/123/maps
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
292 # too much though)
293 #
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
297 if(CYGWIN)
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")
302 else()
303 set(znc_link "znc")
304 set(lib_type "STATIC")
305 set(install_lib)
306 set(znclib_pc)
307 endif()
308
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)
315
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
322 VERBATIM)
323 add_dependencies(msg_after_all ${_all_targets})
324 # @echo ""
325 # @echo " ZNC was successfully compiled."
326 # @echo " Use '$(MAKE) install' to install ZNC to '$(prefix)'."
327
328
329 configure_file("ZNCConfig.cmake.in" "ZNCConfig.cmake" @ONLY)
330 include(CMakePackageConfigHelpers)
331 write_basic_package_version_file("ZNCConfigVersion.cmake"
332 COMPATIBILITY AnyNewerVersion)
333 install(FILES
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}")
340
341 configure_file("znc.pc.cmake.in" "znc.pc" @ONLY)
342 install(FILES "${PROJECT_BINARY_DIR}/znc.pc"
343 DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
344
345 macro(summary_line text var)
346 if(${var})
347 list(APPEND summary_lines "${text} : yes")
348 else()
349 list(APPEND summary_lines "${text} : no")
350 endif()
351 endmacro()
352 set(summary_lines
353 "ZNC ${ZNC_VERSION}${VERSION_EXTRA}${alpha_version} configured"
354 " "
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}")
366
367 include(render_framed_multiline)
368 render_framed_multiline("${summary_lines}")
369
370 message("")
371 message("Now you can run 'make' to compile ZNC")
372 message("")
373
374 # TODO
375 # ====
376 #
377 # remove old configure.ac and Makefile.in