]> jfr.im git - irc/evilnet/znc.git/blob - CMakeLists.txt
Merge pull request #1383 from Phansa/master
[irc/evilnet/znc.git] / CMakeLists.txt
1 #
2 # Copyright (C) 2004-2016 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.0)
19 set(ZNC_VERSION 1.7.x)
20 set(append_git_version true)
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 "" CACHE STRING "Python version to use, or empty")
133 if(WANT_PYTHON AND NOT ICU_FOUND)
134 message(FATAL_ERROR "Modpython requires ZNC to be compiled with charset "
135 "support, but ICU library not found")
136 endif()
137 tristate_option(SWIG "Use SWIG to generate modperl and modpython")
138 set(search_swig false)
139 if(WANT_SWIG AND TRISTATE_SWIG_REQUIRED)
140 set(search_swig true)
141 endif()
142 if(WANT_PERL AND NOT EXISTS
143 "${PROJECT_SOURCE_DIR}/modules/modperl/generated.tar.gz")
144 if(WANT_SWIG)
145 set(search_swig true)
146 else()
147 message(FATAL_ERROR "Pregenerated modperl files are not available. "
148 "SWIG is required. Alternatively, build ZNC from tarball.")
149 endif()
150 endif()
151 if(WANT_PYTHON AND NOT EXISTS
152 "${PROJECT_SOURCE_DIR}/modules/modpython/generated.tar.gz")
153 if(WANT_SWIG)
154 set(search_swig true)
155 else()
156 message(FATAL_ERROR "Pregenerated modpython files are not available. "
157 "SWIG is required. Alternatively, build ZNC from tarball.")
158 endif()
159 endif()
160 if(search_swig)
161 find_package(SWIG 3.0.0)
162 if(NOT SWIG_FOUND)
163 message(FATAL_ERROR
164 "Can't find SWIG, therefore Perl and Python aren't supported. "
165 "Alternatively, build ZNC from tarball.")
166 endif()
167 endif()
168
169 if(WANT_PERL)
170 find_package(PerlLibs 5.10 REQUIRED)
171 endif()
172 if (WANT_PYTHON)
173 find_package(Perl 5.10 REQUIRED)
174 if(WANT_PYTHON_VERSION)
175 find_package(PythonLibs "${WANT_PYTHON_VERSION}" EXACT REQUIRED)
176 else()
177 find_package(PythonLibs 3 REQUIRED)
178 endif()
179 endif()
180
181 set(WANT_TCL false CACHE BOOL "Support Tcl modules")
182 if(WANT_TCL)
183 find_package(TCL QUIET)
184 if(NOT TCL_FOUND)
185 message(FATAL_ERROR "Can't find Tcl")
186 endif()
187 endif()
188
189 tristate_option(I18N "Native language support (i18n)")
190 if(WANT_I18N)
191 find_package(Boost ${TRISTATE_I18N_REQUIRED} COMPONENTS locale)
192 find_package(Gettext ${TRISTATE_I18N_REQUIRED})
193 endif()
194 if(Boost_LOCALE_FOUND AND GETTEXT_MSGFMT_EXECUTABLE)
195 set(HAVE_I18N true)
196 else()
197 set(HAVE_I18N false)
198 endif()
199
200 if(HAVE_I18N AND GETTEXT_MSGMERGE_EXECUTABLE)
201 find_program(XGETTEXT_EXECUTABLE xgettext)
202 if(XGETTEXT_EXECUTABLE)
203 add_custom_target(translation)
204 endif()
205 endif()
206
207 # poll() is broken on Mac OS, it fails with POLLNVAL for pipe()s.
208 if(APPLE)
209 set(CSOCK_USE_POLL false)
210 else()
211 set(CSOCK_USE_POLL true)
212 endif()
213
214 check_cxx_symbol_exists(getopt_long "getopt.h" HAVE_GETOPT_LONG)
215 check_cxx_symbol_exists(lstat "sys/types.h;sys/stat.h;unistd.h" HAVE_LSTAT)
216 check_cxx_symbol_exists(getpassphrase "stdlib.h" HAVE_GETPASSPHRASE)
217 check_cxx_symbol_exists(tcsetattr "termios.h;unistd.h" HAVE_TCSETATTR)
218 check_cxx_symbol_exists(clock_gettime "time.h" HAVE_CLOCK_GETTIME)
219
220 # Note that old broken systems, such as OpenBSD, NetBSD, which don't support
221 # AI_ADDRCONFIG, also have thread-unsafe getaddrinfo(). Gladly, they fixed
222 # thread-safety before support of AI_ADDRCONFIG, so this can be abused to
223 # detect the thread-safe getaddrinfo().
224 #
225 # TODO: drop support of blocking DNS at some point. OpenBSD supports
226 # AI_ADDRCONFIG since Nov 2014, and their getaddrinfo() is thread-safe since
227 # Nov 2013. NetBSD's one is thread-safe since ages ago.
228 check_cxx_symbol_exists(AI_ADDRCONFIG "sys/types.h;sys/socket.h;netdb.h"
229 HAVE_THREADED_DNS)
230
231 if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT CYGWIN)
232 # These enable some debug options in g++'s STL, e.g. invalid use of
233 # iterators, but they cause crashes on cygwin while loading modules
234 set(_GLIBCXX_DEBUG true)
235 set(_GLIBCXX_DEBUG_PEDANTIC true)
236 endif()
237
238 if(append_git_version)
239 find_package(Git)
240 endif()
241
242
243
244 file(GLOB csocket_files LIST_DIRECTORIES FALSE
245 "${PROJECT_SOURCE_DIR}/third_party/Csocket/Csocket.*")
246 if(csocket_files STREQUAL "")
247 message(FATAL_ERROR " It looks like git submodules are not initialized.\n"
248 " Run: git submodule update --init --recursive")
249 endif()
250
251 install(DIRECTORY webskins
252 DESTINATION "${CMAKE_INSTALL_DATADIR}/znc")
253 install(DIRECTORY man/
254 DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
255 FILES_MATCHING PATTERN "znc*")
256
257 set(WANT_SYSTEMD false CACHE BOOL "Install znc.service to systemd")
258 if(WANT_SYSTEMD)
259 configure_file("znc.service.in" "znc.service")
260 set(SYSTEMD_DIR "" CACHE PATH "Path to systemd units")
261 if(SYSTEMD_DIR STREQUAL "" AND PKG_CONFIG_EXECUTABLE)
262 execute_process(COMMAND "${PKG_CONFIG_EXECUTABLE}"
263 --variable=systemdsystemunitdir systemd
264 OUTPUT_VARIABLE SYSTEMD_DIR)
265 endif()
266 if(SYSTEMD_DIR STREQUAL "")
267 message(FATAL_ERROR "Systemd is enabled, "
268 "but the unit dir can't be found.")
269 endif()
270 install(FILES "${PROJECT_BINARY_DIR}/znc.service"
271 DESTINATION "${SYSTEMD_DIR}")
272 endif()
273
274 # On cygwin, if to link modules against znc.exe directly, modperl can't call
275 # ZNC's functions very well. They do get called, but global variables have
276 # different addresses. That address actually is in modperl/ZNC.dll if to look
277 # at /proc/123/maps
278 # Example of such global variable is one returned by CZNC::Get()
279 # Modpython seems to work though with STATIC on cygwin... (I didn't test it
280 # too much though)
281 #
282 # Non-cygwin should link modules to /usr/bin/znc directly to prevent this:
283 # error while loading shared libraries: libznc.so: cannot open shared object file: No such file or directory
284 # Without need to touch LD_LIBRARY_PATH
285 if(CYGWIN)
286 set(znc_link "znclib")
287 set(lib_type "SHARED")
288 set(install_lib "znclib")
289 set(znclib_pc "-L${CMAKE_INSTALL_FULL_LIBDIR} -lznc")
290 else()
291 set(znc_link "znc")
292 set(lib_type "STATIC")
293 set(install_lib)
294 set(znclib_pc)
295 endif()
296
297 configure_file("include/znc/zncconfig.h.cmake.in" "include/znc/zncconfig.h")
298 add_subdirectory(include)
299 add_subdirectory(src)
300 add_subdirectory(modules)
301 add_subdirectory(test)
302 add_subdirectory(zz_msg)
303
304 add_custom_target(msg_after_all ALL
305 COMMAND "${CMAKE_COMMAND}" -E echo
306 COMMAND "${CMAKE_COMMAND}" -E echo " ZNC was successfully compiled."
307 COMMAND "${CMAKE_COMMAND}" -E echo
308 " Use 'make install' to install ZNC to '${CMAKE_INSTALL_PREFIX}'."
309 COMMAND "${CMAKE_COMMAND}" -E echo
310 VERBATIM)
311 add_dependencies(msg_after_all ${_all_targets})
312 # @echo ""
313 # @echo " ZNC was successfully compiled."
314 # @echo " Use '$(MAKE) install' to install ZNC to '$(prefix)'."
315
316
317 configure_file("ZNCConfig.cmake.in" "ZNCConfig.cmake" @ONLY)
318 include(CMakePackageConfigHelpers)
319 write_basic_package_version_file("ZNCConfigVersion.cmake"
320 COMPATIBILITY AnyNewerVersion)
321 install(FILES
322 "${PROJECT_BINARY_DIR}/ZNCConfig.cmake"
323 "${PROJECT_BINARY_DIR}/ZNCConfigVersion.cmake"
324 DESTINATION "${CMAKE_INSTALL_DATADIR}/znc/cmake")
325 configure_file("znc-buildmod.cmake.in" "znc-buildmod" @ONLY)
326 install(PROGRAMS "${PROJECT_BINARY_DIR}/znc-buildmod"
327 DESTINATION "${CMAKE_INSTALL_BINDIR}")
328
329 configure_file("znc.pc.cmake.in" "znc.pc" @ONLY)
330 install(FILES "${PROJECT_BINARY_DIR}/znc.pc"
331 DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
332
333 macro(summary_line text var)
334 if(${var})
335 list(APPEND summary_lines "${text} : yes")
336 else()
337 list(APPEND summary_lines "${text} : no")
338 endif()
339 endmacro()
340 set(summary_lines
341 "ZNC ${ZNC_VERSION}${VERSION_EXTRA}${alpha_version} configured"
342 " "
343 "Prefix : ${CMAKE_INSTALL_PREFIX}")
344 summary_line("SSL " "${OPENSSL_FOUND}")
345 summary_line("IPv6 " "${WANT_IPV6}")
346 summary_line("Async DNS" "${HAVE_THREADED_DNS}")
347 summary_line("Perl " "${PERLLIBS_FOUND}")
348 summary_line("Python " "${PYTHONLIBS_FOUND}")
349 summary_line("Tcl " "${TCL_FOUND}")
350 summary_line("Cyrus " "${CYRUS_FOUND}")
351 summary_line("Charset " "${ICU_FOUND}")
352 summary_line("Zlib " "${ZLIB_FOUND}")
353 summary_line("i18n " "${HAVE_I18N}")
354
355 include(render_framed_multiline)
356 render_framed_multiline("${summary_lines}")
357
358 message("")
359 message("Now you can run 'make' to compile ZNC")
360 message("")
361
362 # TODO
363 # ====
364 #
365 # remove old configure.ac and Makefile.in