CMakeLists.txt revision 99a1ad0f
1# Copyright (c) 2017 - 2021 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)
10OPTION(LSQUIC_SHARED_LIB "Compile as shared librarry" OFF)
11OPTION(LSQUIC_DEVEL "Compile in development mode" OFF)
12
13INCLUDE(GNUInstallDirs)
14
15IF (CMAKE_SYSTEM_NAME STREQUAL "Linux")
16    # If using older glibc, need to link with -lrt.  See clock_getres(2).
17    EXECUTE_PROCESS(
18        COMMAND ${PROJECT_SOURCE_DIR}/print-glibc-version.sh ${CMAKE_C_COMPILER}
19        OUTPUT_VARIABLE GLIBC_VERSION)
20    IF(NOT GLIBC_VERSION EQUAL "" AND GLIBC_VERSION VERSION_LESS 2.17)
21        SET(LIBS ${LIBS} rt)
22    ENDIF()
23ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Android")
24    # for android-ndk >= r19b
25    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY "BOTH")
26    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE "BOTH")
27    set(CMAKE_FIND_ROOT_PATH_MODE_PATH "BOTH")
28ENDIF()
29
30IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
31    SET(CMAKE_BUILD_TYPE Debug)
32ENDIF()
33
34MESSAGE(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
35
36IF (NOT "$ENV{EXTRA_CFLAGS}" MATCHES "-DLSQUIC_DEBUG_NEXT_ADV_TICK")
37    SET(MY_CMAKE_FLAGS "-DLSQUIC_DEBUG_NEXT_ADV_TICK=1")
38ENDIF()
39
40IF (NOT "$ENV{EXTRA_CFLAGS}" MATCHES "-DLSQUIC_CONN_STATS=")
41    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_CONN_STATS=1")
42ENDIF()
43
44IF (NOT MSVC)
45
46SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wall -Wextra -Wno-unused-parameter")
47SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fno-omit-frame-pointer")
48
49IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.3)
50    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wno-missing-field-initializers")
51ENDIF()
52
53IF(LSQUIC_FIU)
54    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DFIU_ENABLE=1")
55    SET(LIBS ${LIBS} fiu)
56ENDIF()
57
58IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
59    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -O0 -g3")
60    IF(CMAKE_C_COMPILER MATCHES "clang" AND
61                        NOT "$ENV{TRAVIS}" MATCHES "^true$" AND
62                        NOT "$ENV{EXTRA_CFLAGS}" MATCHES "-fsanitize")
63        SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fsanitize=address")
64        SET(LIBS ${LIBS} -fsanitize=address)
65    ENDIF()
66    # Uncomment to enable cleartext protocol mode (no crypto):
67    #SET (MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_ENABLE_HANDSHAKE_DISABLE=1")
68ELSE()
69    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -O3 -g0")
70    # Comment out the following line to compile out debug messages:
71    #SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_LOWEST_LOG_LEVEL=LSQ_LOG_INFO")
72ENDIF()
73
74IF (LSQUIC_DEVEL)
75    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_DEVEL=1")
76ENDIF()
77
78IF(LSQUIC_PROFILE EQUAL 1)
79    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -g -pg")
80ENDIF()
81
82IF(LSQUIC_COVERAGE EQUAL 1)
83    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fprofile-arcs -ftest-coverage")
84ENDIF()
85
86IF(MY_CMAKE_FLAGS MATCHES "fsanitize=address")
87    MESSAGE(STATUS "AddressSanitizer is ON")
88ELSE()
89    MESSAGE(STATUS "AddressSanitizer is OFF")
90ENDIF()
91
92#MSVC
93ELSE()
94SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4100")	# unreferenced formal parameter
95SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4115")	# unnamed type definition in parentheses
96SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4116")	# named type definition in parentheses
97SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4146")	# unary minus operator applied to unsigned type, result still unsigned
98SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4132")	# const initialization
99SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4200")	# zero-sized array
100SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4204")	# non-constant aggregate initializer
101SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4244")	# integer conversion
102SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4245")	# conversion from 'int' to 'unsigned int', signed/unsigned mismatch
103SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4267")	# integer conversion
104SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4214")	# nonstandard extension used: bit field types other than int
105SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4295")	# array is too small to include a terminating null character
106SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4334")	# result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
107SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4456")	# hide previous local declaration
108SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4459")	# hide global declaration
109SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4706")	# assignment within conditional expression
110SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4090")	# different 'const' qualifier (TODO: debug ls-sfparser.c)
111SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4305")	# truncation from double to float
112SET(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")
113IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
114    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Od")
115    #SET (MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DFIU_ENABLE=1")
116    #SET(LIBS ${LIBS} fiu)
117ELSE()
118    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Ox")
119    # Comment out the following line to compile out debug messages:
120    #SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_LOWEST_LOG_LEVEL=LSQ_LOG_INFO")
121ENDIF()
122
123ENDIF() #MSVC
124
125set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}  ${MY_CMAKE_FLAGS} $ENV{EXTRA_CFLAGS}")
126
127MESSAGE(STATUS "Compiler flags: ${CMAKE_C_FLAGS}")
128
129find_package(Perl)
130IF(NOT PERL_FOUND)
131    MESSAGE(FATAL_ERROR "Perl not found -- need it to generate source code")
132ENDIF()
133
134IF(LSQUIC_SHARED_LIB)
135    SET(LIB_SUFFIX .so)
136ELSE()
137    SET(LIB_SUFFIX .a)
138ENDIF()
139
140IF (NOT DEFINED BORINGSSL_INCLUDE AND DEFINED BORINGSSL_DIR)
141    FIND_PATH(BORINGSSL_INCLUDE NAMES openssl/ssl.h
142                PATHS ${BORINGSSL_DIR}/include
143                NO_DEFAULT_PATH)
144ENDIF()
145# This must be done before adding other include directories to take
146# precedence over header files from other SSL installs.
147
148IF (BORINGSSL_INCLUDE)
149    MESSAGE(STATUS "BoringSSL include directory ${BORINGSSL_INCLUDE}")
150    INCLUDE_DIRECTORIES(${BORINGSSL_INCLUDE})
151ELSE()
152    MESSAGE(FATAL_ERROR "BoringSSL headers not found")
153ENDIF()
154
155IF (NOT DEFINED BORINGSSL_LIB AND DEFINED BORINGSSL_DIR)
156    FOREACH(LIB_NAME ssl crypto decrepit)
157        IF (CMAKE_SYSTEM_NAME STREQUAL Windows)
158            FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME}
159                NAMES ${LIB_NAME}
160                PATHS ${BORINGSSL_DIR}/${LIB_NAME}
161		PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo
162                NO_DEFAULT_PATH)
163        ELSE()
164            FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME}
165                NAMES lib${LIB_NAME}${LIB_SUFFIX}
166                PATHS ${BORINGSSL_DIR}/${LIB_NAME}
167                NO_DEFAULT_PATH)
168        ENDIF()
169        IF(BORINGSSL_LIB_${LIB_NAME})
170            MESSAGE(STATUS "Found ${LIB_NAME} library: ${BORINGSSL_LIB_${LIB_NAME}}")
171        ELSE()
172            MESSAGE(STATUS "${LIB_NAME} library not found")
173        ENDIF()
174    ENDFOREACH()
175
176ELSE()
177
178
179    FOREACH(LIB_NAME ssl crypto decrepit)
180        IF (CMAKE_SYSTEM_NAME STREQUAL Windows)
181            FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME}
182                NAMES ${LIB_NAME}
183                PATHS ${BORINGSSL_LIB}
184                PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo
185                NO_DEFAULT_PATH)
186        ELSE()
187            FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME}
188                NAMES lib${LIB_NAME}${LIB_SUFFIX}
189                PATHS ${BORINGSSL_LIB}
190                PATH_SUFFIXES ${LIB_NAME}
191                NO_DEFAULT_PATH)
192        ENDIF()
193        IF(BORINGSSL_LIB_${LIB_NAME})
194            MESSAGE(STATUS "Found ${BORINGSSL_LIB} library: ${BORINGSSL_LIB_${LIB_NAME}}")
195        ELSE()
196            MESSAGE(STATUS "${BORINGSSL_LIB} library not found")
197        ENDIF()
198    ENDFOREACH()
199
200ENDIF()
201
202SET(CMAKE_INCLUDE_CURRENT_DIR ON)
203INCLUDE_DIRECTORIES(include)
204IF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")
205    # Find libevent on FreeBSD:
206    include_directories( /usr/local/include )
207    link_directories( /usr/local/lib )
208ENDIF()
209
210# Find zlib and libevent header files and library files
211# TODO: libevent is not strictly necessary to build the library.
212FIND_PATH(ZLIB_INCLUDE_DIR NAMES zlib.h)
213IF (ZLIB_INCLUDE_DIR)
214    INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
215ELSE()
216    MESSAGE(FATAL_ERROR "zlib.h was not found")
217ENDIF()
218IF (CMAKE_SYSTEM_NAME STREQUAL Windows)
219    FIND_LIBRARY(ZLIB_LIB zlib)
220ELSEIF(CMAKE_SYSTEM_NAME STREQUAL Darwin)
221    # XXX somehow FIND_LIBRARY() does not find zlib on Travis?
222    SET(ZLIB_LIB z)
223ELSE()
224    FIND_LIBRARY(ZLIB_LIB libz${LIB_SUFFIX})
225ENDIF()
226IF(ZLIB_LIB)
227    MESSAGE(STATUS "Found zlib: ${ZLIB_LIB}")
228ELSE()
229    MESSAGE(STATUS "zlib not found")
230ENDIF()
231
232SET(LIBS lsquic ${BORINGSSL_LIB_ssl} ${BORINGSSL_LIB_crypto} ${ZLIB_LIB} ${LIBS})
233
234IF (LSQUIC_BIN)
235    FIND_PATH(EVENT_INCLUDE_DIR NAMES event2/event.h)
236    IF (EVENT_INCLUDE_DIR)
237        INCLUDE_DIRECTORIES(${EVENT_INCLUDE_DIR})
238    ELSE()
239        MESSAGE(WARNING "event2/event.h was not found: binaries won't be built")
240        SET(LSQUIC_BIN OFF)
241    ENDIF()
242ENDIF()
243
244IF (LSQUIC_BIN)
245    IF (CMAKE_SYSTEM_NAME STREQUAL Windows)
246        FIND_LIBRARY(EVENT_LIB event)
247    ELSE()
248        FIND_LIBRARY(EVENT_LIB libevent${LIB_SUFFIX})
249        IF(NOT EVENT_LIB)
250            FIND_LIBRARY(EVENT_LIB libevent.so)
251        ENDIF()
252    ENDIF()
253    IF(EVENT_LIB)
254        MESSAGE(STATUS "Found event: ${EVENT_LIB}")
255    ELSE()
256        MESSAGE(WARNING "libevent not found: binaries won't be built")
257        SET(LSQUIC_BIN OFF)
258    ENDIF()
259ENDIF()
260
261
262IF (NOT MSVC)
263    LIST(APPEND LIBS pthread m)
264ELSE()
265    LIST(APPEND LIBS ws2_32)
266ENDIF()
267
268IF (LSQUIC_BIN)
269    ADD_SUBDIRECTORY(bin)
270ENDIF()
271
272add_subdirectory(src)
273
274IF(LSQUIC_TESTS AND CMAKE_BUILD_TYPE STREQUAL "Debug")
275    # Our test framework relies on assertions, only compile if assertions are
276    # enabled.
277    #
278    enable_testing()
279    add_subdirectory(tests)
280ENDIF()
281
282
283FIND_PROGRAM(SPHINX NAMES sphinx-build)
284IF(SPHINX)
285    ADD_CUSTOM_TARGET(docs
286        ${SPHINX} -b html
287        docs
288        docs/_build
289    )
290ELSE()
291    MESSAGE(STATUS "sphinx-build not found: docs won't be made")
292ENDIF()
293
294INSTALL(FILES
295    include/lsquic.h
296    include/lsquic_types.h
297    include/lsxpack_header.h
298    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lsquic
299)
300