diff --git a/.cmake-format.json b/.cmake-format.json new file mode 100644 index 000000000..a4ae98bf4 --- /dev/null +++ b/.cmake-format.json @@ -0,0 +1,10 @@ +{ + "format": { + "tab_size": 4, + "xcommand_case": "lower", + "xkeyword_case": "upper" + }, + "markup": { + "first_comment_is_literal": true + } +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e928c9e2..925d840d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,338 +1,193 @@ # Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. -cmake_minimum_required(VERSION 3.0...3.23) +cmake_minimum_required(VERSION 3.1...3.23) +project(lsquic C) -PROJECT(lsquic C) +option(LSQUIC_FIU "Use Fault Injection in Userspace (FIU)" OFF) +option(LSQUIC_BIN "Compile example binaries that use the library" ON) +option(LSQUIC_TESTS "Compile library unit tests" ON) +option(LSQUIC_DEVEL "Compile in development mode" OFF) +option(LSQUIC_DEBUG_NEXT_ADV_TICK "Define LSQUIC_DEBUG_NEXT_ADV_TICK to 1" ON) +option(LSQUIC_CONN_STATS "Track and print some connection stats" ON) +option(LSQUIC_ENABLE_HANDSHAKE_DISABLE "Disable crypto (plaintext only)" OFF) +option(LSQUIC_COMPILE_OUT_DEBUG_MESSAGES "Disable debug messages" OFF) +option(LSQUIC_SANITIZER "Enable address sanitizer" OFF) +option(BUILD_SHARED_LIBS "Compile as shared library" OFF) -OPTION(LSQUIC_FIU "Use Fault Injection in Userspace (FIU)" OFF) -OPTION(LSQUIC_BIN "Compile example binaries that use the library" ON) -OPTION(LSQUIC_TESTS "Compile library unit tests" ON) -OPTION(LSQUIC_SHARED_LIB "Compile as shared librarry" OFF) -OPTION(LSQUIC_DEVEL "Compile in development mode" OFF) +include(GNUInstallDirs) -INCLUDE(GNUInstallDirs) +message(STATUS "CMake v${CMAKE_VERSION}") -MESSAGE(STATUS "CMake v${CMAKE_VERSION}") - -IF (CMAKE_SYSTEM_NAME STREQUAL "Linux") +set(NEED_LIBRT_FOR_clock_getres OFF) +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") # If using older glibc, need to link with -lrt. See clock_getres(2). - EXECUTE_PROCESS( - COMMAND ${PROJECT_SOURCE_DIR}/print-glibc-version.sh ${CMAKE_C_COMPILER} - OUTPUT_VARIABLE GLIBC_VERSION) - IF(NOT GLIBC_VERSION EQUAL "" AND GLIBC_VERSION VERSION_LESS 2.17) - SET(LIBS ${LIBS} rt) - ENDIF() -ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Android") + include(CheckSymbolExists) + check_symbol_exists(clock_getres "time.h" HAS_clock_getres_WITHOUT_LIBRT) + + if(NOT HAS_clock_getres_WITHOUT_LIBRT) + find_library(RT_LIBRARY rt) + set(NEED_LIBRT_FOR_clock_getres ON) + endif() +elseif(CMAKE_SYSTEM_NAME STREQUAL "Android") # for android-ndk >= r19b set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY "BOTH") set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE "BOTH") set(CMAKE_FIND_ROOT_PATH_MODE_PATH "BOTH") -ENDIF() - -IF("${CMAKE_BUILD_TYPE}" STREQUAL "") - SET(CMAKE_BUILD_TYPE Debug) -ENDIF() - -MESSAGE(STATUS "Build type: ${CMAKE_BUILD_TYPE}") - -IF (NOT "$ENV{EXTRA_CFLAGS}" MATCHES "-DLSQUIC_DEBUG_NEXT_ADV_TICK") - SET(MY_CMAKE_FLAGS "-DLSQUIC_DEBUG_NEXT_ADV_TICK=1") -ENDIF() - -IF (NOT "$ENV{EXTRA_CFLAGS}" MATCHES "-DLSQUIC_CONN_STATS=") - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_CONN_STATS=1") -ENDIF() - -IF (NOT MSVC) - -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wall -Wextra -Wno-unused-parameter") -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fno-omit-frame-pointer") +endif() -IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.3) - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wno-missing-field-initializers") -ENDIF() +if(NOT MSVC) + include(CheckCCompilerFlag) + check_c_compiler_flag(-Wno-implicit-fallthrough HAS_NO_IMPLICIT_FALLTHROUGH) -IF(LSQUIC_FIU) - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DFIU_ENABLE=1") - SET(LIBS ${LIBS} fiu) -ENDIF() + set(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wall -Wextra -Wno-unused-parameter") -IF(CMAKE_BUILD_TYPE STREQUAL "Debug") - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -O0 -g3") - IF(CMAKE_C_COMPILER MATCHES "clang" AND - NOT "$ENV{TRAVIS}" MATCHES "^true$" AND - NOT "$ENV{EXTRA_CFLAGS}" MATCHES "-fsanitize") - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fsanitize=address") - SET(LIBS ${LIBS} -fsanitize=address) - ENDIF() - # Uncomment to enable cleartext protocol mode (no crypto): - #SET (MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_ENABLE_HANDSHAKE_DISABLE=1") -ELSE() - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -O3 -g0") - # Comment out the following line to compile out debug messages: - #SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_LOWEST_LOG_LEVEL=LSQ_LOG_INFO") -ENDIF() + if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS + 4.9.3) + set(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wno-missing-field-initializers") + endif() -IF (LSQUIC_DEVEL) - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_DEVEL=1") -ENDIF() + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -O0 -g3") + else() + set(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -O3 -g0") + endif() -IF(LSQUIC_PROFILE EQUAL 1) - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -g -pg") -ENDIF() + if(LSQUIC_SANITIZER) + message(STATUS "AddressSanitizer is ON") + else() + message(STATUS "AddressSanitizer is OFF") + endif() -IF(LSQUIC_COVERAGE EQUAL 1) - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fprofile-arcs -ftest-coverage") -ENDIF() - -IF(MY_CMAKE_FLAGS MATCHES "fsanitize=address") - MESSAGE(STATUS "AddressSanitizer is ON") -ELSE() - MESSAGE(STATUS "AddressSanitizer is OFF") -ENDIF() - -#MSVC -ELSE() -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4100") # unreferenced formal parameter -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4115") # unnamed type definition in parentheses -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4116") # named type definition in parentheses -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4146") # unary minus operator applied to unsigned type, result still unsigned -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4132") # const initialization -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4200") # zero-sized array -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4204") # non-constant aggregate initializer -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4244") # integer conversion -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4245") # conversion from 'int' to 'unsigned int', signed/unsigned mismatch -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4267") # integer conversion -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4214") # nonstandard extension used: bit field types other than int -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4295") # array is too small to include a terminating null character -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4334") # result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4456") # hide previous local declaration -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4459") # hide global declaration -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4706") # assignment within conditional expression -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4090") # different 'const' qualifier (TODO: debug ls-sfparser.c) -SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} /wd4305") # truncation from double to float -SET(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") -IF(LSQUIC_SHARED_LIB) - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_SHARED_LIB") -ENDIF() -IF(CMAKE_BUILD_TYPE STREQUAL "Debug") - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Od") - #SET (MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DFIU_ENABLE=1") - #SET(LIBS ${LIBS} fiu) -ELSE() - SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Ox") - # Comment out the following line to compile out debug messages: - #SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -DLSQUIC_LOWEST_LOG_LEVEL=LSQ_LOG_INFO") -ENDIF() - -ENDIF() #MSVC +endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_CMAKE_FLAGS} $ENV{EXTRA_CFLAGS}") -MESSAGE(STATUS "Compiler flags: ${CMAKE_C_FLAGS}") +message(STATUS "Compiler flags: ${CMAKE_C_FLAGS}") find_package(Perl) -IF(NOT PERL_FOUND) - MESSAGE(FATAL_ERROR "Perl not found -- need it to generate source code") -ENDIF() - -IF (MSVC) - IF(LSQUIC_SHARED_LIB) - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS YES CACHE BOOL "Export all symbols") - SET(LIB_SUFFIX .dll) - ELSE() - SET(LIB_SUFFIX .lib) - ENDIF() -ELSE() - IF(LSQUIC_SHARED_LIB) - SET(LIB_SUFFIX .so) - ELSE() - SET(LIB_SUFFIX .a) - ENDIF() -ENDIF() - -IF (NOT DEFINED BORINGSSL_INCLUDE AND DEFINED BORINGSSL_DIR) - FIND_PATH(BORINGSSL_INCLUDE NAMES openssl/ssl.h - PATHS ${BORINGSSL_DIR}/include - NO_DEFAULT_PATH) -ENDIF() -# This must be done before adding other include directories to take -# precedence over header files from other SSL installs. - -IF (BORINGSSL_INCLUDE) - MESSAGE(STATUS "BoringSSL include directory ${BORINGSSL_INCLUDE}") - INCLUDE_DIRECTORIES(${BORINGSSL_INCLUDE}) -ELSE() - MESSAGE(FATAL_ERROR "BoringSSL headers not found") -ENDIF() - -IF (NOT DEFINED BORINGSSL_LIB AND DEFINED BORINGSSL_DIR) - FOREACH(LIB_NAME ssl crypto decrepit) - IF (CMAKE_SYSTEM_NAME STREQUAL Windows) - FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME} - NAMES ${LIB_NAME} - PATHS ${BORINGSSL_DIR}/${LIB_NAME} - PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo - NO_DEFAULT_PATH) - ELSE() - FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME} - NAMES lib${LIB_NAME}${LIB_SUFFIX} - PATHS ${BORINGSSL_DIR}/${LIB_NAME} - NO_DEFAULT_PATH) - ENDIF() - IF(BORINGSSL_LIB_${LIB_NAME}) - MESSAGE(STATUS "Found ${LIB_NAME} library: ${BORINGSSL_LIB_${LIB_NAME}}") - ELSE() - MESSAGE(STATUS "${LIB_NAME} library not found") - ENDIF() - ENDFOREACH() - -ELSE() - - - FOREACH(LIB_NAME ssl crypto decrepit) - # If BORINGSSL_LIB is defined, try find each lib. Otherwise, user should define BORINGSSL_LIB_ssl, - # BORINGSSL_LIB_crypto and so on explicitly. For example, including boringssl and lsquic both via - # add_subdirectory: - # add_subdirectory(third_party/boringssl) - # set(BORINGSSL_LIB_ssl ssl) - # set(BORINGSSL_LIB_crypto crypto) - # set(BORINGSSL_LIB_decrepit decrepit) - # add_subdirectory(third_party/lsquic) - IF (DEFINED BORINGSSL_LIB) - IF (CMAKE_SYSTEM_NAME STREQUAL Windows) - FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME} - NAMES ${LIB_NAME} - PATHS ${BORINGSSL_LIB} - PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo - NO_DEFAULT_PATH) - ELSE() - FIND_LIBRARY(BORINGSSL_LIB_${LIB_NAME} - NAMES lib${LIB_NAME}${LIB_SUFFIX} - PATHS ${BORINGSSL_LIB} - PATH_SUFFIXES ${LIB_NAME} - NO_DEFAULT_PATH) - ENDIF() - ENDIF() - IF(BORINGSSL_LIB_${LIB_NAME}) - MESSAGE(STATUS "Found ${LIB_NAME} library: ${BORINGSSL_LIB_${LIB_NAME}}") - ELSE() - MESSAGE(FATAL_ERROR "BORINGSSL_LIB_${LIB_NAME} library not found") - ENDIF() - ENDFOREACH() - -ENDIF() - -SET(CMAKE_INCLUDE_CURRENT_DIR ON) -INCLUDE_DIRECTORIES(include) -IF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") +if(NOT PERL_FOUND) + message(FATAL_ERROR "Perl not found -- need it to generate source code") +endif() + +if(BUILD_SHARED_LIBS) + if(MSVC) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS + YES + CACHE BOOL "Export all symbols") + set(LIB_SUFFIX ${CMAKE_IMPORT_LIBRARY_SUFFIX}) + else() + set(LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) + endif() +else() + set(LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX}) +endif() + +if(NOT DEFINED BORINGSSL_INCLUDE AND DEFINED BORINGSSL_DIR) + find_path( + BORINGSSL_INCLUDE + NAMES openssl/ssl.h + PATHS ${BORINGSSL_DIR}/include + NO_DEFAULT_PATH) +endif() +# This must be done before adding other include directories to take precedence +# over header files from other SSL installs. + +if(BORINGSSL_INCLUDE) + message(STATUS "BoringSSL include directory ${BORINGSSL_INCLUDE}") + include_directories(${BORINGSSL_INCLUDE}) +else() + message(FATAL_ERROR "BoringSSL headers not found") +endif() + +foreach(LIB_NAME ssl crypto decrepit) + find_library( + BORINGSSL_LIB_${LIB_NAME} + NAMES ${LIB_NAME} lib${LIB_NAME} + PATHS ${BORINGSSL_DIR}/${LIB_NAME} ${BORINGSSL_LIB} + PATH_SUFFIXES Debug Release MinSizeRel RelWithDebInfo + NO_DEFAULT_PATH) + if(BORINGSSL_LIB_${LIB_NAME}) + message( + STATUS "Found ${LIB_NAME} library: ${BORINGSSL_LIB_${LIB_NAME}}") + else() + message(STATUS "${LIB_NAME} library not found") + endif() +endforeach() + +set(CMAKE_INCLUDE_CURRENT_DIR ON) +include_directories(include) +if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") # Find libevent on FreeBSD: - include_directories( /usr/local/include ) - link_directories( /usr/local/lib ) -ENDIF() - -IF (CMAKE_SYSTEM_NAME STREQUAL Windows) - FIND_PATH(GETOPT_INCLUDE_DIR NAMES getopt.h) - IF (GETOPT_INCLUDE_DIR) - INCLUDE_DIRECTORIES(${GETOPT_INCLUDE_DIR}) - ELSE() - MESSAGE(FATAL_ERROR "getopt.h was not found") - ENDIF() - FIND_LIBRARY(GETOPT_LIB getopt) - IF(GETOPT_LIB) - MESSAGE(STATUS "Found getopt: ${GETOPT_LIB}") - ELSE() - MESSAGE(STATUS "getopt not found") - ENDIF() -ENDIF() - -# Find zlib and libevent header files and library files -# TODO: libevent is not strictly necessary to build the library. -FIND_PATH(ZLIB_INCLUDE_DIR NAMES zlib.h) -IF (ZLIB_INCLUDE_DIR) - INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) -ELSE() - MESSAGE(FATAL_ERROR "zlib.h was not found") -ENDIF() -IF (CMAKE_SYSTEM_NAME STREQUAL Windows) - FIND_LIBRARY(ZLIB_LIB zlib) -ELSEIF(CMAKE_SYSTEM_NAME STREQUAL Darwin) - # XXX somehow FIND_LIBRARY() does not find zlib on Travis? - SET(ZLIB_LIB z) -ELSE() - FIND_LIBRARY(ZLIB_LIB libz${LIB_SUFFIX}) -ENDIF() -IF(ZLIB_LIB) - MESSAGE(STATUS "Found zlib: ${ZLIB_LIB}") -ELSE() - MESSAGE(STATUS "zlib not found") -ENDIF() - -SET(LIBS lsquic ${BORINGSSL_LIB_ssl} ${BORINGSSL_LIB_crypto} ${ZLIB_LIB} ${LIBS}) - -IF (LSQUIC_BIN) - FIND_PATH(EVENT_INCLUDE_DIR NAMES event2/event.h) - IF (EVENT_INCLUDE_DIR) - INCLUDE_DIRECTORIES(${EVENT_INCLUDE_DIR}) - ELSE() - MESSAGE(WARNING "event2/event.h was not found: binaries won't be built") - SET(LSQUIC_BIN OFF) - ENDIF() -ENDIF() - -IF (LSQUIC_BIN) - IF (CMAKE_SYSTEM_NAME STREQUAL Windows) - FIND_LIBRARY(EVENT_LIB event) - ELSE() - FIND_LIBRARY(EVENT_LIB libevent${LIB_SUFFIX}) - IF(NOT EVENT_LIB) - FIND_LIBRARY(EVENT_LIB libevent.so) - ENDIF() - ENDIF() - IF(EVENT_LIB) - MESSAGE(STATUS "Found event: ${EVENT_LIB}") - ELSE() - MESSAGE(WARNING "libevent not found: binaries won't be built") - SET(LSQUIC_BIN OFF) - ENDIF() -ENDIF() - - -IF (NOT MSVC) - LIST(APPEND LIBS pthread m) -ELSE() - LIST(APPEND LIBS ws2_32) -ENDIF() - -IF (LSQUIC_BIN) - ADD_SUBDIRECTORY(bin) -ENDIF() + include_directories(/usr/local/include) + link_directories(/usr/local/lib) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL Windows) + find_path(GETOPT_INCLUDE_DIR NAMES getopt.h) + if(GETOPT_INCLUDE_DIR) + include_directories(${GETOPT_INCLUDE_DIR}) + else() + message(FATAL_ERROR "getopt.h was not found") + endif() + find_library(GETOPT_LIB getopt) + if(GETOPT_LIB) + message(STATUS "Found getopt: ${GETOPT_LIB}") + else() + message(STATUS "getopt not found") + endif() +endif() + +# Find zlib and libevent header files and library files TODO: libevent is not +# strictly necessary to build the library. +find_package(ZLIB REQUIRED) + +set(LIBS lsquic ${BORINGSSL_LIB_ssl} ${BORINGSSL_LIB_crypto} ${ZLIB_LIB}) + +if(LSQUIC_BIN) + find_path(EVENT_INCLUDE_DIR NAMES event2/event.h) + if(NOT EVENT_INCLUDE_DIR) + message(WARNING "event2/event.h was not found: binaries won't be built") + set(LSQUIC_BIN OFF) + endif() +endif() + +if(LSQUIC_BIN) + find_library(EVENT_LIB NAMES event libevent) + if(EVENT_LIB) + message(STATUS "Found event: ${EVENT_LIB}") + else() + message(WARNING "libevent not found: binaries won't be built") + set(LSQUIC_BIN OFF) + endif() +endif() +find_package(Threads REQUIRED) + +if(NOT MSVC) + list(APPEND LIBS m) +else() + list(APPEND LIBS ws2_32) +endif() + +if(LSQUIC_BIN) + add_subdirectory(bin) +endif() add_subdirectory(src) -IF(LSQUIC_TESTS AND CMAKE_BUILD_TYPE STREQUAL "Debug") +if(LSQUIC_TESTS AND CMAKE_BUILD_TYPE STREQUAL "Debug") # Our test framework relies on assertions, only compile if assertions are # enabled. # enable_testing() add_subdirectory(tests) -ENDIF() - +endif() -FIND_PROGRAM(SPHINX NAMES sphinx-build) -IF(SPHINX) - ADD_CUSTOM_TARGET(docs - ${SPHINX} -b html - docs - docs/_build - ) -ELSE() - MESSAGE(STATUS "sphinx-build not found: docs won't be made") -ENDIF() +find_program(SPHINX NAMES sphinx-build) +if(SPHINX) + add_custom_target(docs ${SPHINX} -b html docs docs/_build) +else() + message(STATUS "sphinx-build not found: docs won't be made") +endif() -INSTALL(FILES - include/lsquic.h - include/lsquic_types.h - include/lsxpack_header.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lsquic -) +install(FILES include/lsquic.h include/lsquic_types.h include/lsxpack_header.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lsquic) diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index 34f9cacf1..414ad331a 100644 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -1,114 +1,90 @@ # Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. include_directories(${CMAKE_CURRENT_BINARY_DIR}) -LIST(APPEND LIBS ${EVENT_LIB}) - -IF(MSVC) - FIND_LIBRARY(PCRE_LIB pcre) - IF(PCRE_LIB) - MESSAGE(STATUS "Found pcre: ${PCRE_LIB}") - LIST(APPEND LIBS ${PCRE_LIB}) - ELSE() - MESSAGE(STATUS "pcre not found: http_server won't work") - ENDIF() - FIND_LIBRARY(PCREPOSIX_LIB pcreposix) - IF(PCREPOSIX_LIB) - MESSAGE(STATUS "Found pcreposix: ${PCREPOSIX_LIB}") - LIST(APPEND LIBS ${PCREPOSIX_LIB}) - ELSE() - MESSAGE(STATUS "pcreposix not found: http_server won't work") - ENDIF() - LIST(APPEND LIBS ws2_32) - LIST(APPEND LIBS iphlpapi) - LIST(APPEND LIBS ${GETOPT_LIB}) -ENDIF() - -add_executable(http_server http_server.c prog.c test_common.c test_cert.c) -IF(NOT MSVC) # TODO: port MD5 server and client to Windows -add_executable(md5_server md5_server.c prog.c test_common.c test_cert.c) -add_executable(md5_client md5_client.c prog.c test_common.c test_cert.c) -ENDIF() -add_executable(echo_server echo_server.c prog.c test_common.c test_cert.c) -add_executable(echo_client echo_client.c prog.c test_common.c test_cert.c) -add_executable(duck_server duck_server.c prog.c test_common.c test_cert.c) -add_executable(duck_client duck_client.c prog.c test_common.c test_cert.c) -add_executable(perf_client perf_client.c prog.c test_common.c test_cert.c) -add_executable(perf_server perf_server.c prog.c test_common.c test_cert.c) - - -IF (NOT MSVC) - -add_executable(http_client - http_client.c - prog.c - test_common.c - test_cert.c -) - -#MSVC -ELSE() - -add_executable(http_client - http_client.c - prog.c - test_common.c - test_cert.c -) - -ENDIF() - -TARGET_LINK_LIBRARIES(http_client ${LIBS}) -TARGET_LINK_LIBRARIES(http_server ${LIBS}) -IF(NOT MSVC) -TARGET_LINK_LIBRARIES(md5_server ${LIBS}) -TARGET_LINK_LIBRARIES(md5_client ${LIBS}) -ENDIF() -TARGET_LINK_LIBRARIES(echo_server ${LIBS}) -TARGET_LINK_LIBRARIES(echo_client ${LIBS}) -TARGET_LINK_LIBRARIES(duck_server ${LIBS}) -TARGET_LINK_LIBRARIES(duck_client ${LIBS}) -TARGET_LINK_LIBRARIES(perf_client ${LIBS}) -TARGET_LINK_LIBRARIES(perf_server ${LIBS}) - - -INCLUDE(CheckFunctionExists) -CHECK_FUNCTION_EXISTS(sendmmsg HAVE_SENDMMSG) -CHECK_FUNCTION_EXISTS(recvmmsg HAVE_RECVMMSG) -CHECK_FUNCTION_EXISTS(open_memstream HAVE_OPEN_MEMSTREAM) - - -INCLUDE(CheckSymbolExists) - -CHECK_SYMBOL_EXISTS( - IP_MTU_DISCOVER - "netinet/in.h" - HAVE_IP_MTU_DISCOVER -) - -CHECK_SYMBOL_EXISTS( - IP_DONTFRAG - "netinet/in.h" - HAVE_IP_DONTFRAG -) - -CHECK_SYMBOL_EXISTS( - preadv - "sys/uio.h" - HAVE_PREADV -) - -INCLUDE(CheckIncludeFiles) - -IF (MSVC AND PCRE_LIB) -FIND_PATH(EVENT_INCLUDE_DIR NAMES pcreposix.h) -IF (EVENT_INCLUDE_DIR) - MESSAGE(STATUS "found pcreposix.h") - SET(HAVE_REGEX 1) -ELSE() - MESSAGE(FATAL_ERROR "event2/event.h was not found") -ENDIF() -ELSE() -CHECK_INCLUDE_FILES(regex.h HAVE_REGEX) -ENDIF() - -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/test_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/test_config.h) +add_library(example_common_objects STATIC prog.c test_common.c test_cert.c) +target_link_libraries(example_common_objects PUBLIC ${LIBS} ${EVENT_LIB} Threads::Threads) +target_include_directories(example_common_objects PUBLIC ${EVENT_INCLUDE_DIR}) + +if(MSVC) + find_library(PCRE_LIB pcre) + if(PCRE_LIB) + message(STATUS "Found pcre: ${PCRE_LIB}") + else() + message(STATUS "pcre not found: http_server won't work") + endif() + find_library(PCREPOSIX_LIB pcreposix) + if(PCREPOSIX_LIB) + message(STATUS "Found pcreposix: ${PCREPOSIX_LIB}") + else() + message(STATUS "pcreposix not found: http_server won't work") + endif() + target_link_libraries(example_common_objects PUBLIC ws2_32 iphlpapi + ${GETOPT_LIB}) +endif() + +add_executable(http_client http_client.c) +target_link_libraries(http_client PRIVATE example_common_objects) + +if(NOT MSVC OR (PCRE_LIB AND PCREPOSIX_LIB)) + add_executable(http_server http_server.c) + target_link_libraries(http_server PRIVATE example_common_objects) + if(MSVC) + target_link_libraries(http_server PRIVATE ${PCRE_LIB} ${PCREPOSIX_LIB}) + endif() +endif() + +if(NOT MSVC) # TODO: port MD5 server and client to Windows + add_executable(md5_server md5_server.c) + target_link_libraries(md5_server PRIVATE example_common_objects) + + add_executable(md5_client md5_client.c) + target_link_libraries(md5_client PRIVATE example_common_objects) +endif() + +add_executable(echo_server echo_server.c) +target_link_libraries(echo_server PRIVATE example_common_objects) + +add_executable(echo_client echo_client.c) +target_link_libraries(echo_client PRIVATE example_common_objects) + +add_executable(duck_server duck_server.c) +target_link_libraries(duck_server PRIVATE example_common_objects) + +add_executable(duck_client duck_client.c) +target_link_libraries(duck_client PRIVATE example_common_objects) + +add_executable(perf_client perf_client.c) +target_link_libraries(perf_client PRIVATE example_common_objects) + +add_executable(perf_server perf_server.c) +target_link_libraries(perf_server PRIVATE example_common_objects) + +include(CheckFunctionExists) +check_function_exists(sendmmsg HAVE_SENDMMSG) +check_function_exists(recvmmsg HAVE_RECVMMSG) +check_function_exists(open_memstream HAVE_OPEN_MEMSTREAM) + +include(CheckSymbolExists) + +check_symbol_exists(IP_MTU_DISCOVER "netinet/in.h" HAVE_IP_MTU_DISCOVER) + +check_symbol_exists(IP_DONTFRAG "netinet/in.h" HAVE_IP_DONTFRAG) + +check_symbol_exists(preadv "sys/uio.h" HAVE_PREADV) + +include(CheckIncludeFiles) + +if(MSVC AND PCRE_LIB) + find_path(EVENT_INCLUDE_DIR NAMES pcreposix.h) + if(EVENT_INCLUDE_DIR) + message(STATUS "found pcreposix.h") + set(HAVE_REGEX 1) + else() + message(FATAL_ERROR "event2/event.h was not found") + endif() +else() + check_include_files(regex.h HAVE_REGEX) +endif() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test_config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/test_config.h) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 356322f3f..389497a4b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ # Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. -cmake_minimum_required(VERSION 3.0...3.23) +cmake_minimum_required(VERSION 3.1...3.23) add_subdirectory(liblsquic) diff --git a/src/liblsquic/CMakeLists.txt b/src/liblsquic/CMakeLists.txt index 87fce00b4..e544c672e 100644 --- a/src/liblsquic/CMakeLists.txt +++ b/src/liblsquic/CMakeLists.txt @@ -1,5 +1,15 @@ # Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. -SET(lsquic_STAT_SRCS +set(lsquic_EXTRA_SRCS) + +if(NOT (PROJECT_NAME STREQUAL "openlitespeed")) + list(APPEND lsquic_EXTRA_SRCS lsquic_xxhash.c ../lshpack/lshpack.c) +endif() + +# library type controlled by BUILD_SHARED_LIBS if STATIC or SHARED not +# explicitly specified +add_library( + lsquic + ${lsquic_EXTRA_SRCS} ls-qpack/lsqpack.c lsquic_adaptive_cc.c lsquic_alarmset.c @@ -82,57 +92,160 @@ SET(lsquic_STAT_SRCS lsquic_util.c lsquic_varint.c lsquic_version.c -) - -IF(NOT MSVC) - SET(QPACK_FLAGS "-Wno-uninitialized") - INCLUDE(CheckCCompilerFlag) - CHECK_C_COMPILER_FLAG(-Wno-implicit-fallthrough HAS_NO_IMPLICIT_FALLTHROUGH) - IF (HAS_NO_IMPLICIT_FALLTHROUGH) - SET(QPACK_FLAGS "${QPACK_FLAGS} -Wno-implicit-fallthrough") - ENDIF() -set_source_files_properties(ls-qpack/lsqpack.c PROPERTIES COMPILE_FLAGS ${QPACK_FLAGS}) -ENDIF() - -include_directories(ls-qpack) - -IF(PROJECT_NAME STREQUAL "openlitespeed") - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/spdy) -ELSE() - INCLUDE_DIRECTORIES(../lshpack) - SET(lsquic_STAT_SRCS ${lsquic_STAT_SRCS} - lsquic_xxhash.c - ../lshpack/lshpack.c - ) -ENDIF() + ls-sfparser.c + ${CMAKE_CURRENT_BINARY_DIR}/lsquic_versions_to_string.c) +target_link_libraries(lsquic PRIVATE ${BORINGSSL_LIB_ssl} + ${BORINGSSL_LIB_crypto} ZLIB::ZLIB) +target_compile_definitions( + lsquic + PRIVATE "LSQPACK_DEC_LOGGER_HEADER=\"lsquic_qpack_dec_logger.h\"" + "LSQPACK_ENC_LOGGER_HEADER=\"lsquic_qpack_enc_logger.h\"" + "XXH_HEADER_NAME=\"lsquic_xxhash.h\"") +target_include_directories(lsquic PRIVATE ls-qpack) -ADD_CUSTOM_COMMAND( +if(PROJECT_NAME STREQUAL "openlitespeed") + target_include_directories(lsquic PRIVATE ${PROJECT_SOURCE_DIR}/src/spdy) +else() + target_include_directories(lsquic PRIVATE ../lshpack) +endif() +if(MSVC) + target_compile_definitions(lsquic PRIVATE LSQUIC_EXPORTS) + target_link_libraries(lsquic PRIVATE ws2_32) +endif() + +add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lsquic_versions_to_string.c - COMMAND ${PERL} - ARGS ${CMAKE_CURRENT_SOURCE_DIR}/gen-verstrs.pl ${CMAKE_CURRENT_SOURCE_DIR}/../../include/lsquic.h ${CMAKE_CURRENT_BINARY_DIR}/lsquic_versions_to_string.c - DEPENDS ./gen-verstrs.pl ${CMAKE_CURRENT_SOURCE_DIR}/../../include/lsquic.h -) -SET(lsquic_STAT_SRCS ${lsquic_STAT_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/lsquic_versions_to_string.c) -SET(lsquic_STAT_SRCS ${lsquic_STAT_SRCS} ls-sfparser.c) - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DXXH_HEADER_NAME=\\\"lsquic_xxhash.h\\\"") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLSQPACK_ENC_LOGGER_HEADER=\\\"lsquic_qpack_enc_logger.h\\\"") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLSQPACK_DEC_LOGGER_HEADER=\\\"lsquic_qpack_dec_logger.h\\\"") - -IF(LSQUIC_SHARED_LIB) - add_library(lsquic SHARED ${lsquic_STAT_SRCS}) - TARGET_LINK_LIBRARIES(lsquic PRIVATE ${BORINGSSL_LIB_ssl} ${BORINGSSL_LIB_crypto} ${ZLIB_LIB}) - IF(MSVC) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLSQUIC_EXPORTS") - TARGET_LINK_LIBRARIES(lsquic PRIVATE ws2_32.lib) - ENDIF() -ELSE() - add_library(lsquic STATIC ${lsquic_STAT_SRCS}) -ENDIF() - -install(TARGETS lsquic + COMMAND + ${PERL} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/gen-verstrs.pl + ${CMAKE_CURRENT_SOURCE_DIR}/../../include/lsquic.h + ${CMAKE_CURRENT_BINARY_DIR}/lsquic_versions_to_string.c + DEPENDS ./gen-verstrs.pl ${CMAKE_CURRENT_SOURCE_DIR}/../../include/lsquic.h) + +if(WIN32) + target_compile_definitions(lsquic PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX) +endif() +if(MSVC) + target_compile_options(lsquic PRIVATE -W4 -WX -Zi + $,-Od,-Ox>) + target_include_directories( + lsquic + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../wincompat + PUBLIC $ + ) + target_compile_definitions(lsquic PRIVATE _CRT_SECURE_NO_WARNINGS) + + if(BUILD_SHARED_LIBS) + target_compile_definitions(lsquic PRIVATE LSQUIC_SHARED_LIB) + endif() + target_compile_options(lsquic PUBLIC /wd4100) # unreferenced formal + # parameter + target_compile_options(lsquic PUBLIC /wd4115) # unnamed type definition in + # parentheses + target_compile_options(lsquic PUBLIC /wd4116) # named type definition in + # parentheses + target_compile_options( + lsquic PUBLIC /wd4146) # unary minus operator applied to unsigned type, + # result still unsigned + target_compile_options(lsquic PUBLIC /wd4132) # const initialization + target_compile_options(lsquic PUBLIC /wd4200) # zero-sized array + target_compile_options(lsquic PUBLIC /wd4204) # non-constant aggregate + # initializer + target_compile_options(lsquic PUBLIC /wd4244) # integer conversion + target_compile_options( + lsquic PUBLIC /wd4245) # conversion from 'int' to 'unsigned int', + # signed/unsigned mismatch + target_compile_options(lsquic PUBLIC /wd4267) # integer conversion + target_compile_options( + lsquic PUBLIC /wd4214) # nonstandard extension used: bit field types + # other than int + target_compile_options( + lsquic PUBLIC /wd4295) # array is too small to include a terminating + # null character + target_compile_options( + lsquic PUBLIC /wd4334) # result of 32-bit shift implicitly converted to + # 64 bits (was 64-bit shift intended?) + target_compile_options(lsquic PUBLIC /wd4456) # hide previous local + # declaration + target_compile_options(lsquic PUBLIC /wd4459) # hide global declaration + target_compile_options(lsquic PUBLIC /wd4706) # assignment within + # conditional expression + target_compile_options(lsquic PUBLIC /wd4090) # different 'const' qualifier + # (TODO: debug ls-sfparser.c) + target_compile_options(lsquic PUBLIC /wd4305) # truncation from double to + # float +else() + # configure flags for lsqpack.c + set(QPACK_FLAGS "-Wno-uninitialized") + if(HAS_NO_IMPLICIT_FALLTHROUGH) + string(APPEND QPACK_FLAGS " -Wno-implicit-fallthrough") + endif() + set_source_files_properties(ls-qpack/lsqpack.c PROPERTIES COMPILE_FLAGS + ${QPACK_FLAGS}) + + # flags for the whole library + target_compile_options(lsquic PRIVATE -fno-omit-frame-pointer) + + if(LSQUIC_SANITIZER) + target_compile_options(lsquic PRIVATE $) + # This command is introduced in CMake 3.13, so 3.13 is required for + # ASan. + target_link_options(lsquic PRIVATE $) + endif() + + if(LSQUIC_PROFILE) + target_compile_options(lsquic PRIVATE -g -pg) + endif() + + if(LSQUIC_COVERAGE) + target_compile_options(lsquic PUBLIC -fprofile-arcs -ftest-coverage) + endif() +endif() + +if(LSQUIC_FIU) + target_compile_definitions(lsquic PRIVATE FIU_ENABLE=1) + target_link_libraries(lsquic PRIVATE fiu) +endif() +if(NEED_LIBRT_FOR_clock_getres AND RT_LIBRARY) + target_link_libraries(lsquic PRIVATE ${RT_LIBRARY}) +endif() + +if(LSQUIC_DEBUG_NEXT_ADV_TICK) + target_compile_definitions(lsquic PRIVATE LSQUIC_DEBUG_NEXT_ADV_TICK=1) +else() + target_compile_definitions(lsquic PRIVATE LSQUIC_DEBUG_NEXT_ADV_TICK=0) +endif() +if(LSQUIC_CONN_STATS) + target_compile_definitions(lsquic PRIVATE LSQUIC_CONN_STATS=1) +else() + target_compile_definitions(lsquic PRIVATE LSQUIC_CONN_STATS=0) +endif() +if(LSQUIC_ENABLE_HANDSHAKE_DISABLE) + target_compile_definitions(lsquic PRIVATE LSQUIC_ENABLE_HANDSHAKE_DISABLE=1) +endif() +if(LSQUIC_COMPILE_OUT_DEBUG_MESSAGES) + target_compile_definitions(lsquic + PRIVATE LSQUIC_LOWEST_LOG_LEVEL=LSQ_LOG_WARN) +endif() +if(LSQUIC_DEVEL) + target_compile_definitions(lsquic PRIVATE LSQUIC_DEVEL=1) +endif() + +install( + TARGETS lsquic EXPORT lsquic-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} -) + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +target_include_directories( + lsquic PUBLIC $) +configure_file(lsquic-config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/lsquic-config.cmake @ONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lsquic-config.cmake + DESTINATION share/lsquic) + +install( + EXPORT lsquic-targets + DESTINATION share/lsquic + NAMESPACE lsquic:: + FILE lsquic-targets.cmake) diff --git a/src/liblsquic/lsquic-config.cmake b/src/liblsquic/lsquic-config.cmake new file mode 100644 index 000000000..d42007182 --- /dev/null +++ b/src/liblsquic/lsquic-config.cmake @@ -0,0 +1,4 @@ +include("${CMAKE_CURRENT_LIST_DIR}/lsquic-targets.cmake") + +include(CMakeFindDependencyMacro) +find_dependency(ZLIB) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7aee69b62..b0870bf9a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,26 +1,26 @@ # Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. -INCLUDE_DIRECTORIES(../src/liblsquic) - -ENABLE_TESTING() - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLSQUIC_TEST=1") - -IF (MSVC) - SET(LIB_FLAGS "-FORCE:MULTIPLE") -ELSE() - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-value") - IF (CMAKE_C_COMPILER_ID STREQUAL GNU) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-override-init") - ENDIF() - IF (CMAKE_C_COMPILER_ID STREQUAL Clang) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-initializer-overrides") - ENDIF() -ENDIF() +include_directories(../src/liblsquic) + +enable_testing() + +add_definitions(-DLSQUIC_TEST=1) +set(_warning_disable_options) +if(MSVC) + set(LIB_FLAGS "-FORCE:MULTIPLE") +else() + string(APPEND CMAKE_C_FLAGS " -Wno-unused-value") + if(CMAKE_C_COMPILER_ID STREQUAL GNU) + string(APPEND CMAKE_C_FLAGS " -Wno-override-init") + endif() + if(CMAKE_C_COMPILER_ID STREQUAL Clang) + string(APPEND CMAKE_C_FLAGS " -Wno-initializer-overrides") + endif() +endif() include_directories(../src/liblsquic/ls-qpack) -INCLUDE_DIRECTORIES(../src/lshpack) +include_directories(../src/lshpack) -SET(TESTS +set(TESTS ack ackgen_gquic_be ackparse_gquic_be @@ -69,93 +69,96 @@ SET(TESTS trapa varint ver_nego - wuf_gquic_be -) + wuf_gquic_be) -IF (CMAKE_SYSTEM_NAME STREQUAL "Linux") +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") # Linux has fmemopen - SET(TESTS ${TESTS} frame_rw) -ENDIF() - -IF (NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") - # No regexes on Windows - SET(TESTS ${TESTS} ack_merge) - # No open_memstream() on Windows - SET(TESTS ${TESTS} hcsi_reader) - # Takes forever on Windows, for whatever reason. Or maybe it's the - # MS C compilers. Something to investigate... later. - LIST(APPEND TESTS h3_framing) -ENDIF() - - -FOREACH(TEST_NAME ${TESTS}) - ADD_EXECUTABLE(test_${TEST_NAME} test_${TEST_NAME}.c ${ADDL_SOURCES}) - IF(NOT MSVC) - TARGET_LINK_LIBRARIES(test_${TEST_NAME} ${LIBS} ${LIB_FLAGS}) - ELSE() - TARGET_LINK_LIBRARIES(test_${TEST_NAME} ${LIBS} ${GETOPT_LIB} ${LIB_FLAGS}) - # copy any dependencies local to the tests - #IF (${CMAKE_VERSION} VERSION_LESS "3.21.0") - ADD_CUSTOM_COMMAND(TARGET test_${TEST_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy \"$ENV{VCPKG_ROOT}/installed/x64-windows$<$:/debug>/bin/getopt.dll\" \"$\" - COMMAND_EXPAND_LISTS - ) - #ELSE() - # ADD_CUSTOM_COMMAND(TARGET test_${TEST_NAME} POST_BUILD - # COMMAND if not \"\"=="$" ${CMAKE_COMMAND} -E copy $ $ - # COMMAND_EXPAND_LISTS - # ) - #ENDIF() - ENDIF() - ADD_TEST(${TEST_NAME} test_${TEST_NAME}) -ENDFOREACH() - -ADD_EXECUTABLE(test_stream test_stream.c ${ADDL_SOURCES}) -TARGET_LINK_LIBRARIES(test_stream ${LIBS} ${LIB_FLAGS}) -IF(MSVC) - TARGET_LINK_LIBRARIES(test_stream ${GETOPT_LIB}) -ENDIF() -ADD_TEST(stream test_stream) -ADD_TEST(stream_hash test_stream -h) -ADD_TEST(stream_A test_stream -A) -ADD_TEST(stream_hash_A test_stream -A -h) - -IF(NOT MSVC) -ADD_EXECUTABLE(graph_cubic graph_cubic.c ${ADDL_SOURCES}) -TARGET_LINK_LIBRARIES(graph_cubic ${LIBS}) - -ADD_EXECUTABLE(mini_parse mini_parse.c ${ADDL_SOURCES}) -TARGET_LINK_LIBRARIES(mini_parse ${LIBS}) -ENDIF() - -ADD_EXECUTABLE(test_min_heap test_min_heap.c ../src/liblsquic/lsquic_min_heap.c) -ADD_TEST(min_heap test_min_heap) - -SET(MALO_SRC test_malo.c ../src/liblsquic/lsquic_malo.c) -ADD_EXECUTABLE(test_malo_pooled ${MALO_SRC}) -IF(MSVC) - TARGET_LINK_LIBRARIES(test_malo_pooled ${GETOPT_LIB}) -ENDIF() -SET_TARGET_PROPERTIES(test_malo_pooled - PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLSQUIC_USE_POOLS=1") -ADD_TEST(malo_pooled test_malo_pooled) - -ADD_EXECUTABLE(test_malo_nopool ${MALO_SRC}) -IF(MSVC) - TARGET_LINK_LIBRARIES(test_malo_nopool ${GETOPT_LIB}) -ENDIF() -SET_TARGET_PROPERTIES(test_malo_nopool - PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLSQUIC_USE_POOLS=0") -ADD_TEST(malo_nopool test_malo_nopool) - -ADD_EXECUTABLE(test_minmax test_minmax.c ../src/liblsquic/lsquic_minmax.c) -IF(MSVC) - TARGET_LINK_LIBRARIES(test_minmax ${GETOPT_LIB}) -ENDIF() -ADD_TEST(minmax test_minmax) - -ADD_EXECUTABLE(test_rechist test_rechist.c ../src/liblsquic/lsquic_rechist.c) -ADD_TEST(rechist test_rechist) - -ADD_EXECUTABLE(test_trechist test_trechist.c ../src/liblsquic/lsquic_trechist.c) -ADD_TEST(trechist test_trechist) + list(APPEND TESTS frame_rw) +endif() + +if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") + + list( + APPEND + TESTS + # No regexes on Windows + ack_merge + # No open_memstream() on Windows + hcsi_reader + # Takes forever on Windows, for whatever reason. Or maybe it's the MS C + # compilers. Something to investigate... later. + h3_framing) +endif() + +foreach(TEST_NAME ${TESTS}) + add_executable(test_${TEST_NAME} test_${TEST_NAME}.c ${ADDL_SOURCES}) + if(NOT MSVC) + target_link_libraries(test_${TEST_NAME} ${LIBS} ${LIB_FLAGS}) + else() + target_link_libraries(test_${TEST_NAME} ${LIBS} ${GETOPT_LIB} + ${LIB_FLAGS}) + # copy any dependencies local to the tests IF (${CMAKE_VERSION} + # VERSION_LESS "3.21.0") + add_custom_command( + TARGET test_${TEST_NAME} + POST_BUILD + COMMAND + ${CMAKE_COMMAND} -E copy + \"$ENV{VCPKG_ROOT}/installed/x64-windows$<$:/debug>/bin/getopt.dll\" + \"$\" + COMMAND_EXPAND_LISTS) + # ELSE() ADD_CUSTOM_COMMAND(TARGET test_${TEST_NAME} POST_BUILD COMMAND + # if not \"\"=="$" + # ${CMAKE_COMMAND} -E copy $ + # $ COMMAND_EXPAND_LISTS ) ENDIF() + endif() + add_test(${TEST_NAME} test_${TEST_NAME}) +endforeach() + +add_executable(test_stream test_stream.c ${ADDL_SOURCES}) +target_link_libraries(test_stream ${LIBS} ${LIB_FLAGS}) +if(MSVC) + target_link_libraries(test_stream ${GETOPT_LIB}) +endif() +add_test(stream test_stream) +add_test(stream_hash test_stream -h) +add_test(stream_A test_stream -A) +add_test(stream_hash_A test_stream -A -h) + +if(NOT MSVC) + add_executable(graph_cubic graph_cubic.c ${ADDL_SOURCES}) + target_link_libraries(graph_cubic ${LIBS}) + + add_executable(mini_parse mini_parse.c ${ADDL_SOURCES}) + target_link_libraries(mini_parse ${LIBS}) +endif() + +add_executable(test_min_heap test_min_heap.c ../src/liblsquic/lsquic_min_heap.c) +add_test(min_heap test_min_heap) + +set(MALO_SRC test_malo.c ../src/liblsquic/lsquic_malo.c) +add_executable(test_malo_pooled ${MALO_SRC}) +if(MSVC) + target_link_libraries(test_malo_pooled ${GETOPT_LIB}) +endif() +target_compile_definitions(test_malo_pooled PRIVATE LSQUIC_USE_POOLS=2) +add_test(malo_pooled test_malo_pooled) + +add_executable(test_malo_nopool ${MALO_SRC}) +if(MSVC) + target_link_libraries(test_malo_nopool ${GETOPT_LIB}) +endif() +target_compile_definitions(test_malo_nopool PRIVATE LSQUIC_USE_POOLS=0) +add_test(malo_nopool test_malo_nopool) + +add_executable(test_minmax test_minmax.c ../src/liblsquic/lsquic_minmax.c) +if(MSVC) + target_link_libraries(test_minmax ${GETOPT_LIB}) +endif() +add_test(minmax test_minmax) + +add_executable(test_rechist test_rechist.c ../src/liblsquic/lsquic_rechist.c) +add_test(rechist test_rechist) + +add_executable(test_trechist test_trechist.c ../src/liblsquic/lsquic_trechist.c) +add_test(trechist test_trechist)