cmake_minimum_required(VERSION 3.6.3) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}") include(Utilities) include(CheckIncludeFiles) include(CheckFunctionExists) project(KinesisVideoWebRTCClient LANGUAGES C) # User Flags option(ADD_MUCLIBC "Add -muclibc c flag" OFF) option(BUILD_DEPENDENCIES "Whether or not to build depending libraries from source" ON) option(USE_OPENSSL "Use openssl as crypto library" OFF) option(USE_MBEDTLS "Use mbedtls as crypto library" ON) option(BUILD_STATIC_LIBS "Build all libraries statically. (This includes third-party libraries.)" ON) option(BUILD_OPENSSL_PLATFORM "If buildng OpenSSL what is the target platform" OFF) option(BUILD_LIBSRTP_HOST_PLATFORM "If buildng LibSRTP what is the current platform" OFF) option(BUILD_LIBSRTP_DESTINATION_PLATFORM "If buildng LibSRTP what is the destination platform" OFF) option(BUILD_SAMPLE "Build available samples" OFF) option(ENABLE_DATA_CHANNEL "Enable support for data channel" ON) option(INSTRUMENTED_ALLOCATORS "Enable memory instrumentation" OFF) # Developer Flags option(BUILD_TEST "Build the testing tree." OFF) option(BUILD_BENCHMARK "Build the benchmark tree." OFF) option(CODE_COVERAGE "Enable coverage reporting" OFF) option(COMPILER_WARNINGS "Enable all compiler warnings." OFF) option(ADDRESS_SANITIZER "Build with AddressSanitizer." OFF) option(MEMORY_SANITIZER "Build with MemorySanitizer." OFF) option(THREAD_SANITIZER "Build with ThreadSanitizer." OFF) option(UNDEFINED_BEHAVIOR_SANITIZER "Build with UndefinedBehaviorSanitizer." OFF) option(LINK_PROFILER "Link gperftools profiler" OFF) set(OPEN_SRC_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/open-source" CACHE PATH "Libraries will be downloaded and built in this directory.") if(NOT WIN32) CHECK_INCLUDE_FILES(ifaddrs.h KVSWEBRTC_HAVE_IFADDRS_H) if(NOT KVSWEBRTC_HAVE_IFADDRS_H) message(FATAL_ERROR "Platform should support the ifaddrs interface.") endif() CHECK_FUNCTION_EXISTS(getifaddrs KVSWEBRTC_HAVE_GETIFADDRS) if(NOT KVSWEBRTC_HAVE_GETIFADDRS) message(FATAL_ERROR "Platform should support getifaddrs API.") endif() endif() set(CMAKE_MACOSX_RPATH TRUE) get_filename_component(ROOT "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE) if (LINK_PROFILER) add_link_options("-Wl,--no-as-needed") endif() # static settings if(BUILD_STATIC_LIBS OR WIN32) set(LINKAGE STATIC) # Force CMake to find static libs if(WIN32) SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) else() SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) endif() else() set(LINKAGE SHARED) endif() set(KINESIS_VIDEO_WEBRTC_CLIENT_SRC "${CMAKE_CURRENT_SOURCE_DIR}") message(STATUS "Kinesis Video WebRTC Client path is ${KINESIS_VIDEO_WEBRTC_CLIENT_SRC}") message(STATUS "dependencies install path is ${OPEN_SRC_INSTALL_PREFIX}") # pass ca cert location to sdk add_definitions(-DKVS_CA_CERT_PATH="${CMAKE_SOURCE_DIR}/certs/cert.pem") add_definitions(-DCMAKE_DETECTED_CACERT_PATH) if(USE_OPENSSL) add_definitions(-DKVS_USE_OPENSSL) elseif(USE_MBEDTLS) add_definitions(-DKVS_USE_MBEDTLS) # FIXME: there's probably a better way to inject MBEDTLS_USER_CONFIG_FILE flag without mutating the global CMAKE_C_FLAGS and CMAKE_CXX_FLAGS set(CMAKE_C_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR}/configs -DMBEDTLS_USER_CONFIG_FILE='<config_mbedtls.h>' ${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "-I${CMAKE_CURRENT_SOURCE_DIR}/configs -DMBEDTLS_USER_CONFIG_FILE='<config_mbedtls.h>' ${CMAKE_CXX_FLAGS}") endif() if(BUILD_DEPENDENCIES) if(NOT EXISTS ${OPEN_SRC_INSTALL_PREFIX}) file(MAKE_DIRECTORY ${OPEN_SRC_INSTALL_PREFIX}) endif() set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${OPEN_SRC_INSTALL_PREFIX}/lib/pkgconfig") set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${OPEN_SRC_INSTALL_PREFIX}) message(STATUS "Begin building dependencies.") set(SSL_OPTIONS USE_OPENSSL USE_MBEDTLS) count_true(ENABLED_SSL_OPTION_COUNT ${SSL_OPTIONS}) if(ENABLED_SSL_OPTION_COUNT GREATER "1") message(FATAL_ERROR "Only one of ${SSL_OPTIONS} can be enabled") endif() if (USE_OPENSSL) set(BUILD_ARGS -DBUILD_STATIC_LIBS=${BUILD_STATIC_LIBS} -DBUILD_OPENSSL_PLATFORM=${BUILD_OPENSSL_PLATFORM} -DOPENSSL_EXTRA=${OPENSSL_EXTRA}) build_dependency(openssl ${BUILD_ARGS}) set(OPENSSL_ROOT_DIR ${OPEN_SRC_INSTALL_PREFIX}) elseif(USE_MBEDTLS) set(BUILD_ARGS -DBUILD_STATIC_LIBS=${BUILD_STATIC_LIBS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}) build_dependency(mbedtls ${BUILD_ARGS}) endif() set(BUILD_ARGS -DBUILD_STATIC_LIBS=${BUILD_STATIC_LIBS} -DOPENSSL_DIR=${OPEN_SRC_INSTALL_PREFIX} -DUSE_OPENSSL=${USE_OPENSSL} -DUSE_MBEDTLS=${USE_MBEDTLS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}) build_dependency(websockets ${BUILD_ARGS}) set(BUILD_ARGS -DBUILD_STATIC_LIBS=${BUILD_STATIC_LIBS} -DOPENSSL_DIR=${OPEN_SRC_INSTALL_PREFIX} -DBUILD_LIBSRTP_HOST_PLATFORM=${BUILD_LIBSRTP_HOST_PLATFORM} -DBUILD_LIBSRTP_DESTINATION_PLATFORM=${BUILD_LIBSRTP_DESTINATION_PLATFORM} -DUSE_OPENSSL=${USE_OPENSSL} -DUSE_MBEDTLS=${USE_MBEDTLS} ) build_dependency(srtp ${BUILD_ARGS}) build_dependency(usrsctp) if(BUILD_TEST) build_dependency(gtest) endif() if(BUILD_BENCHMARK) build_dependency(benchmark) endif() if (LINK_PROFILER) build_dependency(gperftools) endif() # building kvsCommonLws also builds kvspic set(BUILD_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DUSE_OPENSSL=${USE_OPENSSL} -DUSE_MBEDTLS=${USE_MBEDTLS} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}) build_dependency(kvsCommonLws ${BUILD_ARGS}) message(STATUS "Finished building dependencies.") endif() ############# find dependent libraries ############ find_package(Threads) find_package(PkgConfig REQUIRED) if (USE_OPENSSL) find_package(OpenSSL REQUIRED) set(OPEN_SRC_INCLUDE_DIRS ${OPEN_SRC_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR}) else() find_package(MbedTLS REQUIRED) set(OPEN_SRC_INCLUDE_DIRS ${OPEN_SRC_INCLUDE_DIRS} ${MBEDTLS_INCLUDE_DIRS}) endif() if (OPEN_SRC_INSTALL_PREFIX) find_library(SRTP_LIBRARIES srtp2 REQUIRED PATHS ${OPEN_SRC_INSTALL_PREFIX}) if (LINK_PROFILER) find_library(GPERFTOOLS_MALLOC_LIBRARIES tcmalloc REQUIRED PATHS ${OPEN_SRC_INSTALL_PREFIX}) find_library(GPERFTOOLS_PROFILER_LIBRARIES profiler REQUIRED PATHS ${OPEN_SRC_INSTALL_PREFIX}) endif() else() find_library(SRTP_LIBRARIES srtp2 REQUIRED ) if (LINK_PROFILER) find_library(GPERFTOOLS_MALLOC_LIBRARIES tcmalloc REQUIRED) find_library(GPERFTOOLS_PROFILER_LIBRARIES profiler REQUIRED) endif() endif() if (WIN32) SET(LIBWEBSOCKETS_LIBRARIES "websockets.lib") else() pkg_check_modules(LIBWEBSOCKETS REQUIRED libwebsockets) endif() # usrsctp dont support pkgconfig yet find_library( Usrsctp NAMES ${USRSCTP_LIBNAME} usrsctp REQUIRED PATHS ${OPEN_SRC_INSTALL_PREFIX}/lib) set(OPEN_SRC_INCLUDE_DIRS ${OPEN_SRC_INCLUDE_DIRS} ${LIBSRTP_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} ${LIBWEBSOCKETS_INCLUDE_DIRS}) link_directories(${LIBSRTP_LIBRARY_DIRS}) link_directories(${LIBWEBSOCKETS_LIBRARY_DIRS}) link_directories(${OPEN_SRC_INSTALL_PREFIX}/lib) ############# find dependent libraries end ############ if("${CMAKE_C_COMPILER_ID}" MATCHES "GNU|Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") if(ADD_MUCLIBC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -muclibc") endif() if(CODE_COVERAGE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -fprofile-arcs -ftest-coverage") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") endif() if(ADDRESS_SANITIZER) enableSanitizer("address") endif() if(MEMORY_SANITIZER) enableSanitizer("memory") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-memory-track-origins") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize-memory-track-origins") endif() if(THREAD_SANITIZER) enableSanitizer("thread") endif() if(UNDEFINED_BEHAVIOR_SANITIZER) enableSanitizer("undefined") endif() endif() # Uncomment below line for debug heap # add_definitions(-DHEAP_DEBUG) # Uncomment below to add thread id in log # add_definitions(-DENABLE_LOG_THREAD_ID) # Uncomment below line for very verbose logging # add_definitions(-DLOG_STREAMING) if (ENABLE_DATA_CHANNEL) add_definitions(-DENABLE_DATA_CHANNEL) endif() if (INSTRUMENTED_ALLOCATORS) add_definitions(-DINSTRUMENTED_ALLOCATORS) endif() add_definitions(-DSUPPORT_H264_AVCC_FRAME) add_definitions(-DSUPPORT_SHARE_BUFFER) file( GLOB WEBRTC_CLIENT_SOURCE_FILES "src/source/Crypto/*.c" "src/source/Ice/*.c" "src/source/PeerConnection/*.c" "src/source/Rtcp/*.c" "src/source/Rtp/*.c" "src/source/Rtp/Codecs/*.c" "src/source/Sdp/*.c" "src/source/Srtp/*.c" "src/source/Stun/*.c" "src/source/Sctp/*.c" "src/source/Metrics/*.c") if (USE_OPENSSL) list(FILTER WEBRTC_CLIENT_SOURCE_FILES EXCLUDE REGEX ".*_mbedtls\\.c") elseif (USE_MBEDTLS) list(FILTER WEBRTC_CLIENT_SOURCE_FILES EXCLUDE REGEX ".*_openssl\\.c") endif() file(GLOB WEBRTC_SIGNALING_CLIENT_SOURCE_FILES "src/source/Signaling/*.c") include_directories(${OPEN_SRC_INCLUDE_DIRS}) include_directories(${OPEN_SRC_INSTALL_PREFIX}/include) include_directories(${KINESIS_VIDEO_WEBRTC_CLIENT_SRC}/src/include) include_directories(${KINESIS_VIDEO_WEBRTC_CLIENT_SRC}/src/ice) add_library(kvsWebrtcClient ${LINKAGE} ${WEBRTC_CLIENT_SOURCE_FILES}) target_link_libraries( kvsWebrtcClient PRIVATE kvspicUtils kvspicState ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} ${SRTP_LIBRARIES} ${Usrsctp} ${MBEDTLS_LIBRARIES} ${GPERFTOOLS_MALLOC_LIBRARIES} ${GPERFTOOLS_PROFILER_LIBRARIES} ${EXTRA_DEPS}) add_library(kvsWebrtcSignalingClient ${LINKAGE} ${WEBRTC_SIGNALING_CLIENT_SOURCE_FILES}) target_link_libraries( kvsWebrtcSignalingClient PUBLIC kvsCommonLws ${LIBWEBSOCKETS_LIBRARIES} PRIVATE kvspicUtils kvspicState ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_DEPS} ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} ${GPERFTOOLS_MALLOC_LIBRARIES} ${GPERFTOOLS_PROFILER_LIBRARIES} ${MBEDTLS_LIBRARIES}) if (WIN32) target_link_libraries(kvsWebrtcClient PRIVATE "Ws2_32" "iphlpapi") endif() if(COMPILER_WARNINGS) target_compile_options(kvsWebrtcClient PUBLIC -Wall -Werror -pedantic -Wextra -Wno-unknown-warning-option) target_compile_options(kvsWebrtcSignalingClient PUBLIC -Wall -Werror -pedantic -Wextra -Wno-unknown-warning-option) endif() install(TARGETS kvsWebrtcClient kvsWebrtcSignalingClient LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) install(DIRECTORY ${KINESIS_VIDEO_WEBRTC_CLIENT_SRC}/src/include/ DESTINATION include ) if (BUILD_SAMPLE) # copy sample frames to build folder, in case developer runs sample program with command `samples/kvsWebrtcClientMaster` from `build` dir. file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/samples/opusSampleFrames" DESTINATION .) file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/samples/h264SampleFrames" DESTINATION .) add_subdirectory(samples) endif() if(BUILD_TEST) add_subdirectory(tst) endif() if(BUILD_BENCHMARK) add_subdirectory(bench) endif()