CMakeLists.txt revision b1a7c3f9
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 IF(CMAKE_C_COMPILER MATCHES "clang" AND 58 NOT "$ENV{TRAVIS}" MATCHES "^true$" AND 59 NOT "$ENV{EXTRA_CFLAGS}" MATCHES "-fsanitize") 60 SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fsanitize=address") 61 SET(LIBS ${LIBS} -fsanitize=address) 62 ENDIF() 63 # Uncomment to enable cleartext protocol mode (no crypto): 64 #SET (MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_ENABLE_HANDSHAKE_DISABLE=1") 65ELSE() 66 SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -O3 -g0") 67 # Comment out the following line to compile out debug messages: 68 #SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_LOWEST_LOG_LEVEL=LSQ_LOG_INFO") 69ENDIF() 70 71IF(LSQUIC_PROFILE EQUAL 1) 72 SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -g -pg") 73ENDIF() 74 75IF(LSQUIC_COVERAGE EQUAL 1) 76 SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fprofile-arcs -ftest-coverage") 77ENDIF() 78 79IF(MY_CMAKE_FLAGS MATCHES "fsanitize=address") 80 MESSAGE(STATUS "AddressSanitizer is ON") 81ELSE() 82 MESSAGE(STATUS "AddressSanitizer is OFF") 83ENDIF() 84 85#MSVC 86ELSE() 87SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4100") # unreferenced formal parameter 88SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4115") # unnamed type definition in parentheses 89SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4116") # named type definition in parentheses 90SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4146") # unary minus operator applied to unsigned type, result still unsigned 91SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4132") # const initialization 92SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4200") # zero-sized array 93SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4204") # non-constant aggregate initializer 94SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4244") # integer conversion 95SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4245") # conversion from 'int' to 'unsigned int', signed/unsigned mismatch 96SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4267") # integer conversion 97SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4214") # nonstandard extension used: bit field types other than int 98SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4295") # array is too small to include a terminating null character 99SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4334") # result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) 100SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4456") # hide previous local declaration 101SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4459") # hide global declaration 102SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4706") # assignment within conditional expression 103SET(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") 104IF(CMAKE_BUILD_TYPE STREQUAL "Debug") 105 SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Od") 106 #SET (MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DFIU_ENABLE=1") 107 #SET(LIBS ${LIBS} fiu) 108ELSE() 109 SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Ox") 110 # Comment out the following line to compile out debug messages: 111 #SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_LOWEST_LOG_LEVEL=LSQ_LOG_INFO") 112ENDIF() 113 114ENDIF() #MSVC 115 116set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_CMAKE_FLAGS} $ENV{EXTRA_CFLAGS}") 117 118MESSAGE(STATUS "Compiler flags: ${CMAKE_C_FLAGS}") 119 120find_package(Perl) 121IF(NOT PERL_FOUND) 122 MESSAGE(FATAL_ERROR "Perl not found -- need it to generate source code") 123ENDIF() 124 125IF (NOT DEFINED BORINGSSL_INCLUDE AND DEFINED BORINGSSL_DIR) 126 FIND_PATH(BORINGSSL_INCLUDE NAMES openssl/ssl.h 127 PATHS ${BORINGSSL_DIR}/include 128 NO_DEFAULT_PATH) 129ENDIF() 130# This must be done before adding other include directories to take 131# precedence over header files from other SSL installs. 132 133IF (BORINGSSL_INCLUDE) 134 MESSAGE(STATUS "BoringSSL include directory ${BORINGSSL_INCLUDE}") 135 INCLUDE_DIRECTORIES(${BORINGSSL_INCLUDE}) 136ELSE() 137 MESSAGE(FATAL_ERROR "BoringSSL headers not found") 138ENDIF() 139 140IF (NOT DEFINED BORINGSSL_LIB AND DEFINED BORINGSSL_DIR) 141 FOREACH(LIB_NAME ssl crypto decrepit) 142 IF (CMAKE_SYSTEM_NAME STREQUAL Windows) 143 FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME} 144 NAMES ${LIB_NAME} 145 PATHS ${BORINGSSL_DIR}/${LIB_NAME} 146 PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo 147 NO_DEFAULT_PATH) 148 ELSE() 149 FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME} 150 NAMES lib${LIB_NAME}.a 151 PATHS ${BORINGSSL_DIR}/${LIB_NAME} 152 NO_DEFAULT_PATH) 153 ENDIF() 154 IF(BORINGSSL_LIB_${LIB_NAME}) 155 MESSAGE(STATUS "Found ${LIB_NAME} library: ${BORINGSSL_LIB_${LIB_NAME}}") 156 ELSE() 157 MESSAGE(STATUS "${LIB_NAME} library not found") 158 ENDIF() 159 ENDFOREACH() 160 161ELSE() 162 163 164 FOREACH(LIB_NAME ssl crypto decrepit) 165 IF (CMAKE_SYSTEM_NAME STREQUAL Windows) 166 FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME} 167 NAMES ${LIB_NAME} 168 PATHS ${BORINGSSL_LIB} 169 PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo 170 NO_DEFAULT_PATH) 171 ELSE() 172 FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME} 173 NAMES lib${LIB_NAME}.a 174 PATHS ${BORINGSSL_LIB} 175 PATH_SUFFIXES ${LIB_NAME} 176 NO_DEFAULT_PATH) 177 ENDIF() 178 IF(BORINGSSL_LIB_${LIB_NAME}) 179 MESSAGE(STATUS "Found ${BORINGSSL_LIB} library: ${BORINGSSL_LIB_${LIB_NAME}}") 180 ELSE() 181 MESSAGE(STATUS "${BORINGSSL_LIB} library not found") 182 ENDIF() 183 ENDFOREACH() 184 185ENDIF() 186 187SET(CMAKE_INCLUDE_CURRENT_DIR ON) 188INCLUDE_DIRECTORIES(include) 189IF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") 190 # Find libevent on FreeBSD: 191 include_directories( /usr/local/include ) 192 link_directories( /usr/local/lib ) 193ENDIF() 194 195# Find zlib and libevent header files and library files 196# TODO: libevent is not strictly necessary to build the library. 197FIND_PATH(ZLIB_INCLUDE_DIR NAMES zlib.h) 198IF (ZLIB_INCLUDE_DIR) 199 INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) 200ELSE() 201 MESSAGE(FATAL_ERROR "zlib.h was not found") 202ENDIF() 203IF (CMAKE_SYSTEM_NAME STREQUAL Windows) 204 FIND_LIBRARY(ZLIB_LIB zlib) 205ELSEIF(CMAKE_SYSTEM_NAME STREQUAL Darwin) 206 # XXX somehow FIND_LIBRARY() does not find zlib on Travis? 207 SET(ZLIB_LIB z) 208ELSE() 209 FIND_LIBRARY(ZLIB_LIB libz.a) 210ENDIF() 211IF(ZLIB_LIB) 212 MESSAGE(STATUS "Found zlib: ${ZLIB_LIB}") 213ELSE() 214 MESSAGE(STATUS "zlib not found") 215ENDIF() 216 217IF (LSQUIC_BIN OR LSQUIC_TESTS) 218FIND_PATH(EVENT_INCLUDE_DIR NAMES event2/event.h) 219IF (EVENT_INCLUDE_DIR) 220 INCLUDE_DIRECTORIES(${EVENT_INCLUDE_DIR}) 221ELSE() 222 MESSAGE(FATAL_ERROR "event2/event.h was not found") 223ENDIF() 224IF (CMAKE_SYSTEM_NAME STREQUAL Windows) 225 FIND_LIBRARY(EVENT_LIB event) 226ELSE() 227 FIND_LIBRARY(EVENT_LIB libevent.a) 228 IF(NOT EVENT_LIB) 229 FIND_LIBRARY(EVENT_LIB libevent.so) 230 ENDIF() 231ENDIF() 232IF(EVENT_LIB) 233 MESSAGE(STATUS "Found event: ${EVENT_LIB}") 234ELSE() 235 MESSAGE(STATUS "libevent not found") 236ENDIF() 237SET(LIBS lsquic ${EVENT_LIB} ${BORINGSSL_LIB_ssl} ${BORINGSSL_LIB_crypto} ${ZLIB_LIB} ${LIBS}) 238IF(MSVC) 239FIND_LIBRARY(PCRE_LIB pcre) 240IF(PCRE_LIB) 241 MESSAGE(STATUS "Found pcre: ${PCRE_LIB}") 242 LIST(APPEND LIBS ${PCRE_LIB}) 243ELSE() 244 MESSAGE(STATUS "pcre not found: http_server won't work") 245ENDIF() 246FIND_LIBRARY(PCREPOSIX_LIB pcreposix) 247IF(PCREPOSIX_LIB) 248 MESSAGE(STATUS "Found pcreposix: ${PCREPOSIX_LIB}") 249 LIST(APPEND LIBS ${PCREPOSIX_LIB}) 250ELSE() 251 MESSAGE(STATUS "pcreposix not found: http_server won't work") 252ENDIF() 253LIST(APPEND LIBS ws2_32) 254ENDIF() 255ENDIF() # LSQUIC_BIN OR LSQUIC_TESTS 256 257IF(LSQUIC_BIN) 258IF(MSVC) 259 SET(GETOPT_C wincompat/getopt.c) 260ENDIF() 261add_executable(http_server bin/http_server.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C}) 262IF(NOT MSVC) # TODO: port MD5 server and client to Windows 263add_executable(md5_server bin/md5_server.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C}) 264add_executable(md5_client bin/md5_client.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C}) 265ENDIF() 266add_executable(echo_server bin/echo_server.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C}) 267add_executable(echo_client bin/echo_client.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C}) 268add_executable(duck_server bin/duck_server.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C}) 269add_executable(duck_client bin/duck_client.c bin/prog.c bin/test_common.c bin/test_cert.c ${GETOPT_C}) 270 271 272IF (NOT MSVC) 273 274add_executable(http_client 275 bin/http_client.c 276 bin/prog.c 277 bin/test_common.c 278 bin/test_cert.c 279) 280LIST(APPEND LIBS pthread m) 281 282#MSVC 283ELSE() 284 285add_executable(http_client 286 bin/http_client.c 287 bin/prog.c 288 bin/test_common.c 289 bin/test_cert.c 290 wincompat/getopt.c 291 wincompat/getopt1.c 292) 293LIST(APPEND LIBS ws2_32) 294 295ENDIF() 296 297TARGET_LINK_LIBRARIES(http_client ${LIBS}) 298TARGET_LINK_LIBRARIES(http_server ${LIBS}) 299IF(NOT MSVC) 300TARGET_LINK_LIBRARIES(md5_server ${LIBS}) 301TARGET_LINK_LIBRARIES(md5_client ${LIBS}) 302ENDIF() 303TARGET_LINK_LIBRARIES(echo_server ${LIBS}) 304TARGET_LINK_LIBRARIES(echo_client ${LIBS}) 305TARGET_LINK_LIBRARIES(duck_server ${LIBS}) 306TARGET_LINK_LIBRARIES(duck_client ${LIBS}) 307 308add_subdirectory(bin) 309ENDIF() # LSQUIC_BIN 310 311add_subdirectory(src) 312 313IF(LSQUIC_TESTS AND CMAKE_BUILD_TYPE STREQUAL "Debug") 314 # Our test framework relies on assertions, only compile if assertions are 315 # enabled. 316 # 317 enable_testing() 318 add_subdirectory(tests) 319ENDIF() 320 321 322FIND_PROGRAM(SPHINX NAMES sphinx-build) 323IF(SPHINX) 324 ADD_CUSTOM_TARGET(docs 325 ${SPHINX} -b html 326 docs 327 docs/_build 328 ) 329ELSE() 330 MESSAGE(STATUS "sphinx-build not found: docs won't be made") 331ENDIF() 332