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