CMakeLists.txt revision 81558c3f
1# Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE.
2cmake_minimum_required(VERSION 2.8)
3
4
5PROJECT(lsquic C)
6
7OPTION(LSQUIC_FIU "Use Fault Injection in Userspace (FIU)" OFF)
8OPTION(LSQUIC_BIN "Compile example binaries that use the library" ON)
9OPTION(LSQUIC_TESTS "Compile library unit tests" ON)
10
11IF (CMAKE_SYSTEM_NAME STREQUAL "Linux")
12    # If using older glibc, need to link with -lrt.  See clock_getres(2).
13    EXECUTE_PROCESS(
14        COMMAND ${PROJECT_SOURCE_DIR}/print-glibc-version.sh ${CMAKE_C_COMPILER}
15        OUTPUT_VARIABLE GLIBC_VERSION)
16    IF(NOT GLIBC_VERSION EQUAL "" AND GLIBC_VERSION VERSION_LESS 2.17)
17        SET(LIBS ${LIBS} rt)
18    ENDIF()
19ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Android")
20    # for android-ndk >= r19b
21    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY "BOTH")
22    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE "BOTH")
23    set(CMAKE_FIND_ROOT_PATH_MODE_PATH "BOTH")
24ENDIF()
25
26IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
27    SET(CMAKE_BUILD_TYPE Debug)
28ENDIF()
29
30MESSAGE(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
31
32IF (NOT "$ENV{EXTRA_CFLAGS}" MATCHES "-DLSQUIC_DEBUG_NEXT_ADV_TICK")
33    SET(MY_CMAKE_FLAGS "-DLSQUIC_DEBUG_NEXT_ADV_TICK=1")
34ENDIF()
35
36IF (NOT MSVC)
37
38SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wall -Wextra -Wno-unused-parameter")
39SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fno-omit-frame-pointer")
40INCLUDE(CheckCCompilerFlag)
41CHECK_C_COMPILER_FLAG(-Wno-implicit-fallthrough HAS_NO_IMPLICIT_FALLTHROUGH)
42IF (HAS_NO_IMPLICIT_FALLTHROUGH)
43    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wno-implicit-fallthrough")
44ENDIF()
45
46IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.3)
47    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wno-missing-field-initializers")
48ENDIF()
49
50IF(LSQUIC_FIU)
51    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DFIU_ENABLE=1")
52    SET(LIBS ${LIBS} fiu)
53ENDIF()
54
55IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
56    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -O0 -g3")
57    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Werror")
58    IF(CMAKE_C_COMPILER MATCHES "clang" AND
59                        NOT "$ENV{TRAVIS}" MATCHES "^true$" AND
60                        NOT "$ENV{EXTRA_CFLAGS}" MATCHES "-fsanitize")
61        SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fsanitize=address")
62        SET(LIBS ${LIBS} -fsanitize=address)
63    ENDIF()
64    # Uncomment to enable cleartext protocol mode (no crypto):
65    #SET (MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_ENABLE_HANDSHAKE_DISABLE=1")
66ELSE()
67    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -O3 -g0")
68    # Comment out the following line to compile out debug messages:
69    #SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_LOWEST_LOG_LEVEL=LSQ_LOG_INFO")
70ENDIF()
71
72IF(LSQUIC_PROFILE EQUAL 1)
73    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -g -pg")
74ENDIF()
75
76IF(LSQUIC_COVERAGE EQUAL 1)
77    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fprofile-arcs -ftest-coverage")
78ENDIF()
79
80IF(MY_CMAKE_FLAGS MATCHES "fsanitize=address")
81    MESSAGE(STATUS "AddressSanitizer is ON")
82ELSE()
83    MESSAGE(STATUS "AddressSanitizer is OFF")
84ENDIF()
85
86#MSVC
87ELSE()
88SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4214")	# nonstandard extension used: bit field types other than int
89SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -W4 -WX -Zi -DWIN32_LEAN_AND_MEAN -DNOMINMAX -D_CRT_SECURE_NO_WARNINGS -I${CMAKE_CURRENT_SOURCE_DIR}/wincompat")
90IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
91    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Od")
92    #SET (MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DFIU_ENABLE=1")
93    #SET(LIBS ${LIBS} fiu)
94ELSE()
95    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Ox")
96    # Comment out the following line to compile out debug messages:
97    #SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_LOWEST_LOG_LEVEL=LSQ_LOG_INFO")
98ENDIF()
99
100ENDIF() #MSVC
101
102set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}  ${MY_CMAKE_FLAGS} $ENV{EXTRA_CFLAGS}")
103
104MESSAGE(STATUS "Compiler flags: ${CMAKE_C_FLAGS}")
105
106IF (NOT DEFINED BORINGSSL_INCLUDE AND DEFINED BORINGSSL_DIR)
107    FIND_PATH(BORINGSSL_INCLUDE NAMES openssl/ssl.h
108                PATHS ${BORINGSSL_DIR}/include
109                NO_DEFAULT_PATH)
110ENDIF()
111# This must be done before adding other include directories to take
112# precedence over header files from other SSL installs.
113
114IF (BORINGSSL_INCLUDE)
115    MESSAGE(STATUS "BoringSSL include directory ${BORINGSSL_INCLUDE}")
116    INCLUDE_DIRECTORIES(${BORINGSSL_INCLUDE})
117ELSE()
118    MESSAGE(FATAL_ERROR "BoringSSL headers not found")
119ENDIF()
120
121IF (NOT DEFINED BORINGSSL_LIB AND DEFINED BORINGSSL_DIR)
122    FOREACH(LIB_NAME ssl crypto decrepit)
123        IF (CMAKE_SYSTEM_NAME STREQUAL Windows)
124            FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME}
125                NAMES ${LIB_NAME}
126                PATHS ${BORINGSSL_DIR}/${LIB_NAME}
127                PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo
128                NO_DEFAULT_PATH)
129        ELSE()
130            FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME}
131                NAMES lib${LIB_NAME}.a
132                PATHS ${BORINGSSL_DIR}/${LIB_NAME}
133                NO_DEFAULT_PATH)
134        ENDIF()
135        IF(BORINGSSL_LIB_${LIB_NAME})
136            MESSAGE(STATUS "Found ${LIB_NAME} library: ${BORINGSSL_LIB_${LIB_NAME}}")
137        ELSE()
138            MESSAGE(STATUS "${LIB_NAME} library not found")
139        ENDIF()
140    ENDFOREACH()
141
142ELSE()
143
144
145    FOREACH(LIB_NAME ssl crypto decrepit)
146        IF (CMAKE_SYSTEM_NAME STREQUAL Windows)
147            FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME}
148                NAMES ${LIB_NAME}
149                PATHS ${BORINGSSL_LIB}
150                PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo
151                NO_DEFAULT_PATH)
152        ELSE()
153            FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME}
154                NAMES lib${LIB_NAME}.a
155                PATHS ${BORINGSSL_LIB}
156                PATH_SUFFIXES ${LIB_NAME}
157                NO_DEFAULT_PATH)
158        ENDIF()
159        IF(BORINGSSL_LIB_${LIB_NAME})
160            MESSAGE(STATUS "Found ${BORINGSSL_LIB} library: ${BORINGSSL_LIB_${LIB_NAME}}")
161        ELSE()
162            MESSAGE(STATUS "${BORINGSSL_LIB} library not found")
163        ENDIF()
164    ENDFOREACH()
165#endif
166
167ENDIF()
168
169SET(CMAKE_INCLUDE_CURRENT_DIR ON)
170INCLUDE_DIRECTORIES(include)
171IF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")
172    # Find libevent on FreeBSD:
173    include_directories( /usr/local/include )
174    link_directories( /usr/local/lib )
175ENDIF()
176
177# Find zlib and libevent header files and library files
178# TODO: libevent is not strictly necessary to build the library.
179FIND_PATH(ZLIB_INCLUDE_DIR NAMES zlib.h)
180IF (ZLIB_INCLUDE_DIR)
181    INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
182ELSE()
183    MESSAGE(FATAL_ERROR "zlib.h was not found")
184ENDIF()
185IF (CMAKE_SYSTEM_NAME STREQUAL Windows)
186    FIND_LIBRARY(ZLIB_LIB zlib)
187ELSEIF(CMAKE_SYSTEM_NAME STREQUAL Darwin)
188    # XXX somehow FIND_LIBRARY() does not find zlib on Travis?
189    SET(ZLIB_LIB z)
190ELSE()
191    FIND_LIBRARY(ZLIB_LIB libz.a)
192ENDIF()
193IF(ZLIB_LIB)
194    MESSAGE(STATUS "Found zlib: ${ZLIB_LIB}")
195ELSE()
196    MESSAGE(STATUS "zlib not found")
197ENDIF()
198
199IF (LSQUIC_BIN)
200FIND_PATH(EVENT_INCLUDE_DIR NAMES event2/event.h)
201IF (EVENT_INCLUDE_DIR)
202    INCLUDE_DIRECTORIES(${EVENT_INCLUDE_DIR})
203ELSE()
204    MESSAGE(FATAL_ERROR "event2/event.h was not found")
205ENDIF()
206IF (CMAKE_SYSTEM_NAME STREQUAL Windows)
207    FIND_LIBRARY(EVENT_LIB event)
208ELSE()
209    FIND_LIBRARY(EVENT_LIB libevent.a)
210    IF(NOT EVENT_LIB)
211        FIND_LIBRARY(EVENT_LIB libevent.so)
212    ENDIF()
213ENDIF()
214IF(EVENT_LIB)
215    MESSAGE(STATUS "Found event: ${EVENT_LIB}")
216ELSE()
217    MESSAGE(STATUS "libevent not found")
218ENDIF()
219
220add_executable(http_server bin/http_server.c bin/prog.c bin/test_common.c bin/test_cert.c)
221add_executable(md5_server bin/md5_server.c bin/prog.c bin/test_common.c bin/test_cert.c)
222add_executable(md5_client bin/md5_client.c bin/prog.c bin/test_common.c bin/test_cert.c)
223add_executable(echo_server bin/echo_server.c bin/prog.c bin/test_common.c bin/test_cert.c)
224add_executable(echo_client bin/echo_client.c bin/prog.c bin/test_common.c bin/test_cert.c)
225
226
227SET(LIBS lsquic ${EVENT_LIB} ${BORINGSSL_LIB_ssl} ${BORINGSSL_LIB_crypto} ${ZLIB_LIB} ${LIBS})
228
229IF (NOT MSVC)
230
231add_executable(http_client
232    bin/http_client.c
233    bin/prog.c
234    bin/test_common.c
235    bin/test_cert.c
236)
237LIST(APPEND LIBS pthread m)
238
239#MSVC
240ELSE()
241
242add_executable(http_client
243    bin/http_client.c
244    bin/prog.c
245    bin/test_common.c
246    wincompat/getopt.c
247    wincompat/getopt1.c
248)
249LIST(APPEND LIBS ws2_32)
250
251ENDIF()
252
253TARGET_LINK_LIBRARIES(http_client ${LIBS})
254TARGET_LINK_LIBRARIES(http_server ${LIBS})
255TARGET_LINK_LIBRARIES(md5_server  ${LIBS})
256TARGET_LINK_LIBRARIES(md5_client  ${LIBS})
257TARGET_LINK_LIBRARIES(echo_server ${LIBS})
258TARGET_LINK_LIBRARIES(echo_client ${LIBS})
259
260add_subdirectory(bin)
261ENDIF() # LSQUIC_BIN
262
263add_subdirectory(src)
264
265IF(LSQUIC_TESTS AND CMAKE_BUILD_TYPE STREQUAL "Debug")
266    # Our test framework relies on assertions, only compile if assertions are
267    # enabled.
268    #
269    enable_testing()
270    add_subdirectory(tests)
271ENDIF()
272
273
274FIND_PROGRAM(SPHINX NAMES sphinx-build)
275IF(SPHINX)
276    ADD_CUSTOM_TARGET(docs
277        ${SPHINX} -b html
278        docs
279        docs/_build
280    )
281ELSE()
282    MESSAGE(STATUS "sphinx-build not found: docs won't be made")
283ENDIF()
284