Cleaned up the CyaSSL linking in the CMake project a bit.
[platform/upstream/libwebsockets.git] / CMakeLists.txt
1 cmake_minimum_required(VERSION 2.6)
2
3 project(libwebsockets)
4
5 set(PACKAGE "libwebsockets")
6 set(PACKAGE_VERSION "1.1")
7 set(PACKAGE_BUGREPORT "andy@warmcat.com")
8 set(PACKAGE_NAME "${PACKAGE}")
9 set(PACKAGE_STRING "${PACKAGE} ${PACKAGE_VERSION}")
10 set(PACKAGE_TARNAME "${PACKAGE}")
11 set(PACKAGE_URL "http://libwebsockets.org")
12 set(VERSION "{PACKAGE_VERSION}")
13
14 set(LWS_LIBRARY_VERSION ${PACKAGE_VERSION})
15
16 # Try to find the current Git hash.
17 find_package(Git)
18 if(GIT_EXECUTABLE)
19         execute_process(
20     COMMAND "${GIT_EXECUTABLE}" log -n 1 --pretty=%h
21     OUTPUT_VARIABLE GIT_HASH
22     OUTPUT_STRIP_TRAILING_WHITESPACE
23     )
24
25     set(LWS_BUILD_HASH ${GIT_HASH})
26     message("Git commit hash: ${LWS_BUILD_HASH}")
27 endif()
28
29 option(WITH_SSL "Include SSL support (default OpenSSL, CyaSSL if USE_CYASSL is set)" ON)
30 option(USE_EXTERNAL_ZLIB "Search the system for ZLib instead of using the included one (on Windows)" OFF)
31 option(USE_CYASSL "Use CyaSSL replacement for OpenSSL" OFF)
32 option(WITH_BUILTIN_GETIFADDRS "Use BSD getifaddrs implementation from libwebsockets... default is your libc provides it" OFF)
33 option(WITHOUT_TESTAPPS "Don't build the libwebsocket-test-apps" OFF)
34 option(WITHOUT_CLIENT "Don't build the client part of the library" OFF)
35 option(WITHOUT_SERVER "Don't build the server part of the library" OFF)
36 option(WITHOUT_SERVER_EXTPOLL "Don't build a server version that uses external poll" OFF)
37 option(WITH_LIBCRYPTO "Use libcrypto MD5 and SHA1 implementations" ON)
38 option(WITHOUT_PING "Don't build the ping test application" OFF)
39 option(WITHOUT_DEBUG "Don't compile debug related code" OFF)
40 option(WITHOUT_EXTENSIONS "Don't compile with extensions" OFF)
41 option(WITH_LATENCY "Build latency measuring code into the library" OFF)
42 option(WITHOUT_DAEMONIZE "Don't build the daemonization api" OFF)
43
44 # The base dir where the SSL dirs should be looked for.
45 set(SSL_CERT_DIR CACHE STRING "")
46 set(SSL_CLIENT_CERT_DIR CACHE STRING "")
47
48 if ("${SSL_CERT_DIR}" STREQUAL "")
49         set(SSL_CERT_DIR ".")
50 endif()
51
52 if ("${SSL_CLIENT_CERT_DIR}" STREQUAL "")
53         set(LWS_OPENSSL_CLIENT_CERTS ".")
54 else()
55         set(LWS_OPENSSL_CLIENT_CERTS "${SSL_CLIENT_CERT_DIR}")
56 endif()
57
58 set(CYASSL_LIB CACHE STRING "")
59 set(CYASSL_INCLUDE_DIRS CACHE STRING "")
60
61 if (USE_CYASSL)
62         if ("${CYASSL_LIB}" STREQUAL "" OR "${CYASSL_INCLUDE_DIRS}" STREQUAL "")
63                 message(FATAL_ERROR "You must set CYASSL_LIB and CYASSL_INCLUDE_DIRS when USE_CYASSL is turned on")
64         endif()
65 endif()
66
67 if (WITHOUT_EXTENSIONS)
68         set(LWS_NO_EXTENSIONS 1)
69 endif()
70
71 if (WITH_SSL)
72         set(LWS_OPENSSL_SUPPORT 1)
73 endif()
74
75 if (WITH_LATENCY)
76         set(LWS_LATENCY 1)
77 endif()
78
79 if (WITHOUT_DAEMONIZE)
80         set(LWS_NO_DAEMONIZE 1)
81 endif()
82
83 if (WITHOUT_SERVER)
84         set(LWS_NO_SERVER 1)
85 endif()
86
87 if (WITHOUT_CLIENT)
88         set(LWS_NO_CLIENT 1)
89 endif()
90
91 if (MINGW)
92         set(LWS_MINGW_SUPPORT 1)
93 endif()
94
95 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/")
96 include_directories(${PROJECT_BINARY_DIR})
97
98 include(CheckCSourceCompiles)
99
100 # Check for different inline keyword versions.
101 foreach(KEYWORD "inline" "__inline__" "__inline")
102         set(CMAKE_REQUIRED_DEFINITIONS "-DKEYWORD=${KEYWORD}")
103         CHECK_C_SOURCE_COMPILES(
104                 "
105                 #include <stdio.h>
106                 KEYWORD void a() {}
107                 int main(int argc, char **argv) { a(); return 0; }
108                 " HAVE_${KEYWORD})
109 endforeach()
110
111 if (NOT HAVE_inline)
112         if (HAVE___inline__)
113                 set(inline __inline__)
114         elseif(HAVE___inline)
115                 set(inline __inline)
116         endif()
117 endif()
118
119 # Put the libaries and binaries that get built into directories at the
120 # top of the build tree rather than in hard-to-find leaf directories. 
121 SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
122 SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
123 SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
124
125 # So we can include the CMake generated config file only when
126 # building with CMAKE.
127 add_definitions(-DCMAKE_BUILD)
128
129 include(CheckFunctionExists)
130 include(CheckIncludeFile)
131 include(CheckIncludeFiles)
132 include(CheckLibraryExists)
133
134 CHECK_FUNCTION_EXISTS(bzero HAVE_BZERO)
135 CHECK_FUNCTION_EXISTS(fork HAVE_FORK)
136 CHECK_FUNCTION_EXISTS(malloc HAVE_MALLOC)
137 CHECK_FUNCTION_EXISTS(memset HAVE_MEMSET)
138 CHECK_FUNCTION_EXISTS(realloc HAVE_REALLOC)
139 CHECK_FUNCTION_EXISTS(socket HAVE_SOCKET)
140 CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR)
141 CHECK_FUNCTION_EXISTS(vfork HAVE_VFORK)
142 CHECK_FUNCTION_EXISTS(getifaddrs HAVE_GETIFADDRS)
143
144 if (WITH_BUILTIN_GETIFADDRS)
145         if (HAVE_GETIFADDRS)
146                 warning("getifaddrs already exists on the system, are you sure you want to build using the BSD version? (This is normally only needed on systems running uclibc)")
147         endif()
148         set(LWS_BUILTIN_GETIFADDRS 1)
149 endif()
150
151 CHECK_INCLUDE_FILE(dlfcn.h HAVE_DLFCN_H)
152 CHECK_INCLUDE_FILE(fcntl.h HAVE_FCNTL_H)
153 CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H)
154 CHECK_INCLUDE_FILE(memory.h HAVE_MEMORY_H)
155 CHECK_INCLUDE_FILE(netinet/in.h HAVE_NETINET_IN_H)
156 CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H)
157 CHECK_INCLUDE_FILE(stdlib.h HAVE_STDLIB_H)
158 CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_H)
159 CHECK_INCLUDE_FILE(string.h HAVE_STRING_H)
160 CHECK_INCLUDE_FILE(sys/prctl.h HAVE_SYS_PRCTL_H)
161 CHECK_INCLUDE_FILE(sys/socket.h HAVE_SYS_SOCKET_H)
162 CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H)
163 CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H)
164 CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
165 CHECK_INCLUDE_FILE(vfork.h HAVE_VFORK_H)
166 CHECK_INCLUDE_FILE(zlib.h HAVE_ZLIB_H)
167
168 # TODO: These can be tested if they actually work also...
169 set(HAVE_WORKING_FORK HAVE_FORK)
170 set(HAVE_WORKING_VFORK HAVE_VFORK)
171
172 CHECK_INCLUDE_FILES("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
173
174 if (NOT HAVE_SYS_TYPES_H)
175         set(pid_t int)
176         set(size_t "unsigned int")
177 endif()
178
179 if (NOT HAVE_MALLOC)
180         set(malloc rpl_malloc)
181 endif()
182
183 if (NOT HAVE_REALLOC)
184         set(realloc rpl_realloc)
185 endif()
186
187 # Generate the config.h that includes all the compilation settings.
188 configure_file(
189                 ${PROJECT_SOURCE_DIR}/config.h.cmake 
190                 ${PROJECT_BINARY_DIR}/lws_config.h)
191
192 set(LIB_LIST)
193
194 if (MSVC)
195         # Turn off stupid microsoft security warnings.
196         add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
197 endif()
198
199 include_directories(${PROJECT_SOURCE_DIR}/lib)
200
201 # Group headers and sources.
202 # Some IDEs use this for nicer file structure.
203 set(HDR_PRIVATE
204         lib/private-libwebsockets.h
205         lib/extension-deflate-frame.h
206         lib/extension-deflate-stream.h
207         ${PROJECT_BINARY_DIR}/lws_config.h
208         )
209
210 set(HDR_PUBLIC  
211         lib/libwebsockets.h
212         )
213
214 set(SOURCES
215         lib/base64-decode.c
216         lib/client.c
217         lib/client-handshake.c
218         lib/client-parser.c
219         lib/extension.c
220         lib/extension-deflate-frame.c
221         lib/extension-deflate-stream.c
222         lib/handshake.c
223         lib/libwebsockets.c
224         lib/minilex.c
225         lib/output.c
226         lib/parsers.c
227         lib/server.c
228         lib/server-handshake.c
229         lib/sha-1.c
230         )
231
232 # Add helper files for Windows.
233 if (WIN32)
234         set(WIN32_HELPERS_PATH win32port/win32helpers)
235
236         list(APPEND HDR_PRIVATE
237                 ${WIN32_HELPERS_PATH}/websock-w32.h
238                 ${WIN32_HELPERS_PATH}/gettimeofday.h
239                 )
240
241         list(APPEND SOURCES 
242                 ${WIN32_HELPERS_PATH}/websock-w32.c
243                 ${WIN32_HELPERS_PATH}/gettimeofday.c
244                 )
245
246         include_directories(${WIN32_HELPERS_PATH})
247 else()
248         # Unix.
249         if (NOT WITHOUT_DAEMONIZE)
250                 list(APPEND SOURCES
251                         lib/daemonize.c
252                         )
253         endif()
254 endif()
255
256 if (UNIX)
257         if (!WITH_BUILTIN_GETIFADDRS)
258                 list(APPEND HDR_PRIVATE lib/getifaddrs.h)
259                 list(APPEND SOURCES lib/getifaddrs.c)
260         endif()
261 endif()
262
263 source_group("Headers Private"  FILES ${HDR_PRIVATE})
264 source_group("Headers Public"   FILES ${HDR_PUBLIC})
265 source_group("Sources"          FILES ${SOURCES})
266
267 #
268 # Create the lib.
269 #
270 add_library(websockets STATIC
271                         ${HDR_PRIVATE}
272                         ${HDR_PUBLIC}
273                         ${SOURCES})
274
275 #
276 # Find libraries.
277 #
278
279 #
280 # ZLIB.
281 #
282 if (WIN32 AND NOT USE_EXTERNAL_ZLIB)
283         message("Using included Zlib version")
284
285         # Compile ZLib if needed.
286         set(WIN32_ZLIB_PATH "win32port/zlib")
287         set(ZLIB_SRCS
288                 ${WIN32_ZLIB_PATH}/adler32.c
289                 ${WIN32_ZLIB_PATH}/compress.c
290                 ${WIN32_ZLIB_PATH}/crc32.c
291                 ${WIN32_ZLIB_PATH}/deflate.c
292                 ${WIN32_ZLIB_PATH}/gzclose.c
293                 ${WIN32_ZLIB_PATH}/gzio.c
294                 ${WIN32_ZLIB_PATH}/gzlib.c
295                 ${WIN32_ZLIB_PATH}/gzread.c
296                 ${WIN32_ZLIB_PATH}/gzwrite.c
297                 ${WIN32_ZLIB_PATH}/infback.c
298                 ${WIN32_ZLIB_PATH}/inffast.c
299                 ${WIN32_ZLIB_PATH}/inflate.c
300                 ${WIN32_ZLIB_PATH}/inftrees.c
301                 ${WIN32_ZLIB_PATH}/trees.c
302                 ${WIN32_ZLIB_PATH}/uncompr.c
303                 ${WIN32_ZLIB_PATH}/zutil.c
304         )
305
306         # Create the library.
307         add_library(ZLIB STATIC ${ZLIB_SRCS})
308
309         # Set the same variables as find_package would.
310         set(ZLIB_INCLUDE_DIRS ${WIN32_ZLIB_PATH})
311         get_property(ZLIB_LIBRARIES TARGET ZLIB PROPERTY LOCATION)
312         set(ZLIB_FOUND 1)
313 else()
314         find_package(ZLIB REQUIRED)
315 endif()
316
317 message("ZLib include dirs: ${ZLIB_INCLUDE_DIRS}")
318 message("ZLib libraries: ${ZLIB_LIBRARIES}")
319 include_directories(${ZLIB_INCLUDE_DIRS})
320 target_link_libraries(websockets ${ZLIB_LIBRARIES})
321
322 #
323 # OpenSSL
324 #
325 if (WITH_SSL)
326         message("Compiling with SSL support")
327
328         if (USE_CYASSL)
329                 # Use CyaSSL as OpenSSL replacement.
330                 # TODO: Add a find_package command for this also.
331                 message("CyaSSL include dir: ${CYASSL_INCLUDE_DIRS}")
332                 message("CyaSSL libraries: ${CYASSL_LIB}")
333
334                 include_directories(${CYASSL_INCLUDE_DIRS})
335                 target_link_libraries(websockets ${CYASSL_LIB})
336         else()
337                 # TODO: Add support for STATIC also.
338                 find_package(OpenSSL REQUIRED)
339
340                 message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}")
341                 message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
342
343                 include_directories(${OPENSSL_INCLUDE_DIR})
344                 target_link_libraries(websockets ${OPENSSL_LIBRARIES})
345         endif()
346 endif(WITH_SSL)
347
348 #
349 # Platform specific libs.
350 #
351 if (WIN32)
352         target_link_libraries(websockets ws2_32.lib)
353 endif()
354
355 if (UNIX)
356         target_link_libraries(websockets m)
357 endif()
358
359 #
360 # Test applications
361 #
362 if (NOT WITHOUT_TESTAPPS)
363         #
364         # Helper function for adding a test app.
365         #
366         function(create_test_app TEST_NAME MAIN_SRC WIN32_SRCS WIN32_HDRS)
367                 
368                 set(TEST_SRCS ${MAIN_SRC})
369                 set(TEST_HDR)
370
371                 if (WIN32)
372                         list(APPEND TEST_SRCS 
373                                 ${WIN32_HELPERS_PATH}/getopt.c
374                                 ${WIN32_HELPERS_PATH}/getopt_long.c
375                                 ${WIN32_HELPERS_PATH}/gettimeofday.c
376                                 ${WIN32_SRCS})
377
378                         list(APPEND TEST_HDR 
379                                 ${WIN32_HELPERS_PATH}/getopt.h
380                                 ${WIN32_HELPERS_PATH}/gettimeofday.h
381                                 ${WIN32_HDRS})
382                 endif(WIN32)
383
384                 source_group("Headers"   FILES ${TEST_HDR})
385                 source_group("Sources"   FILES ${TEST_SRCS})
386                 add_executable(${TEST_NAME} ${TEST_SRCS} ${TEST_HDR})
387                 target_link_libraries(${TEST_NAME} websockets)
388
389                 set_property(
390                                         TARGET ${TEST_NAME}
391                                         PROPERTY COMPILE_DEFINITIONS INSTALL_DATADIR="${SSL_CERT_DIR}"
392                                         )
393         endfunction()
394
395         #
396         # test-client
397         #
398         if (NOT WITHOUT_CLIENT)
399                 create_test_app(test-client
400                         "test-server/test-client.c"
401                         ""
402                         "")
403         endif()
404
405         #
406         # test-server
407         #
408         if (NOT WITHOUT_SERVER)
409                 create_test_app(test-server
410                         "test-server/test-server.c"
411                         ""
412                         "${WIN32_HELPERS_PATH}/netdb.h;${WIN32_HELPERS_PATH}/strings.h;${WIN32_HELPERS_PATH}/unistd.h;${WIN32_HELPERS_PATH}/websock-w32.h")
413         endif()
414
415         #
416         # test-server-extpoll
417         #
418         if (NOT WITHOUT_SERVER AND NOT WITHOUT_SERVER_EXTPOLL)
419                 create_test_app(test-server-extpoll
420                         "test-server/test-server.c"
421                         ""
422                         "${WIN32_HELPERS_PATH}/netdb.h;${WIN32_HELPERS_PATH}/strings.h;${WIN32_HELPERS_PATH}/unistd.h;${WIN32_HELPERS_PATH}/websock-w32.h")
423                         
424                         # Set defines for this executable only.
425                         set_property(
426                                 TARGET test-server-extpoll
427                                 PROPERTY COMPILE_DEFINITIONS EXTERNAL_POLL INSTALL_DATADIR="${SSL_CERT_DIR}"
428                                 )
429         endif()
430
431         #
432         # test-fraggle
433         #
434         if (NOT WITHOUT_FRAGGLE)
435                 create_test_app(test-fraggle
436                         "test-server/test-fraggle.c"
437                         ""
438                         "${WIN32_HELPERS_PATH}/unistd.h;${WIN32_HELPERS_PATH}/sys/time.h")
439         endif()
440
441         #
442         # test-ping
443         #
444         if (NOT WITHOUT_PING)
445                 create_test_app(test-ping
446                         "test-server/test-ping.c"
447                         ""
448                         "${WIN32_HELPERS_PATH}/unistd.h;${WIN32_HELPERS_PATH}/sys/time.h")
449         endif()
450
451         #
452         # Copy OpenSSL dlls to the output directory on Windows.
453         # (Otherwise we'll get an error when trying to run)
454         #
455         if (WIN32 AND WITH_SSL AND NOT USE_CYASSL)
456
457                 message("Searching for OpenSSL dlls")
458                 find_package(OpenSSLbins)
459
460                 if(OPENSSL_BIN_FOUND)
461                         message("OpenSSL dlls found, copying to output directory")
462                         message("Libeay: ${LIBEAY_BIN}")
463                         message("SSLeay: ${SSLEAY_BIN}")
464
465                         foreach(TARGET_BIN 
466                                         test-client 
467                                         test-server
468                                         test-fraggle
469                                         test-echo
470                                         test-ping
471                                         )                       
472                                 add_custom_command(TARGET ${TARGET_BIN}
473                                         POST_BUILD 
474                                         COMMAND ${CMAKE_COMMAND} -E copy ${LIBEAY_BIN} $<TARGET_FILE_DIR:${TARGET_BIN}> VERBATIM)
475                                         
476                                 add_custom_command(TARGET ${TARGET_BIN}
477                                         POST_BUILD 
478                                         COMMAND ${CMAKE_COMMAND} -E copy ${SSLEAY_BIN} $<TARGET_FILE_DIR:${TARGET_BIN}> VERBATIM)
479                         endforeach()
480                 endif()
481         endif()
482 endif(NOT WITHOUT_TESTAPPS)