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