cmake_minimum_required(VERSION 3.12) project(node-webrtc) include(ExternalProject) find_package(Git REQUIRED) find_package(Threads REQUIRED) find_program(iwyu_path OPTIONAL NAMES include-what-you-use iwyu) find_program(clang_tidy_path OPTIONAL NAMES clang-tidy) if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(LINUX TRUE) endif() if ("$ENV{TARGET_ARCH}" STREQUAL "arm") set(ARM TRUE) elseif ("$ENV{TARGET_ARCH}" STREQUAL "arm64") set(ARM64 TRUE) endif() # depot_tools # ----------------------------------------------------------------------------- #[[ ExternalProject_Add( project_depot_tools GIT_REPOSITORY https://chromium.googlesource.com/chromium/tools/depot_tools.git GIT_TAG 650096367cd9900e499052c49179b33b68fa1ac9 PREFIX ${CMAKE_BINARY_DIR}/external/depot_tools/prefix TMP_DIR ${CMAKE_BINARY_DIR}/external/depot_tools/tmp STAMP_DIR ${CMAKE_BINARY_DIR}/external/depot_tools/stamp DOWNLOAD_DIR ${CMAKE_BINARY_DIR}/external/depot_tools/download SOURCE_DIR ${CMAKE_BINARY_DIR}/external/depot_tools/src BINARY_DIR ${CMAKE_BINARY_DIR}/external/depot_tools/build CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" ) ExternalProject_Get_Property(project_depot_tools SOURCE_DIR) set(depot_tools_install_dir ${SOURCE_DIR}) ]] # libc++ # ----------------------------------------------------------------------------- #[[ set(libwebrtc_binary_dir ${CMAKE_BINARY_DIR}/external/libwebrtc/build/${CMAKE_BUILD_TYPE}) set(libwebrtc_src_dir ${CMAKE_BINARY_DIR}/external/libwebrtc/download/src) add_library(libc++ OBJECT IMPORTED) add_dependencies(libc++ libwebrtc) set(libc++_objects algorithm.o any.o atomic.o barrier.o bind.o charconv.o chrono.o condition_variable.o condition_variable_destructor.o debug.o exception.o functional.o future.o hash.o ios.instantiations.o ios.o iostream.o locale.o memory.o mutex.o mutex_destructor.o new.o optional.o random.o random_shuffle.o regex.o shared_mutex.o stdexcept.o string.o strstream.o system_error.o thread.o typeinfo.o utility.o valarray.o variant.o vector.o ) list(TRANSFORM libc++_objects PREPEND ${libwebrtc_binary_dir}/obj/buildtools/third_party/libc++/libc++/) set_property(TARGET libc++ APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) set_target_properties(libc++ PROPERTIES IMPORTED_OBJECTS_DEBUG "${libc++_objects}" IMPORTED_OBJECTS "${libc++_objects}") ]] # NOTE(mroberts): I would like this to be INTERFACE. # # https://gitlab.kitware.com/cmake/cmake/issues/15052 # # target_include_directories(libc++ SYSTEM INTERFACE "${libc++_include_dir}") # libc++abi # ----------------------------------------------------------------------------- add_library(libc++abi OBJECT IMPORTED) add_dependencies(libc++abi libwebrtc) set(libc++abi_objects abort_message.o cxa_aux_runtime.o cxa_default_handlers.o cxa_demangle.o cxa_exception.o cxa_exception_storage.o cxa_guard.o cxa_handlers.o cxa_personality.o #cxa_unexpected.o cxa_vector.o cxa_virtual.o fallback_malloc.o private_typeinfo.o stdlib_exception.o stdlib_stdexcept.o stdlib_typeinfo.o ) list(TRANSFORM libc++abi_objects PREPEND ${libwebrtc_binary_dir}/obj/buildtools/third_party/libc++abi/libc++abi/) set_property(TARGET libc++abi APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) set_target_properties(libc++abi PROPERTIES IMPORTED_OBJECTS_DEBUG "${libc++abi_objects}" IMPORTED_OBJECTS "${libc++abi_objects}") # NOTE(mroberts): I would like this to be INTERFACE. # # https://gitlab.kitware.com/cmake/cmake/issues/15052 # # target_include_directories(libc++abi SYSTEM INTERFACE "${libc++abi_include_dir}") # libwebrtc # ----------------------------------------------------------------------------- set(WEBRTC_REVISION branch-heads/4707) list(APPEND GN_GEN_ARGS ffmpeg_branding=Chrome proprietary_codecs = true rtc_use_h264=true rtc_initialize_ffmpeg=true rtc_build_examples=false rtc_use_x11=false rtc_enable_protobuf=false rtc_use_gtk=false rtc_include_pulse_audio=false rtc_include_tests=false ) if (ARM) list(APPEND GN_GEN_ARGS target_os="linux" target_cpu="arm" rtc_build_tools=true treat_warnings_as_errors=false fatal_linker_warnings=false ) elseif (ARM64) if(NOT APPLE) list(APPEND GN_GEN_ARGS target_os="linux" ) endif() list(APPEND GN_GEN_ARGS target_cpu="arm64" rtc_build_tools=true treat_warnings_as_errors=false fatal_linker_warnings=false ) else() list(APPEND GN_GEN_ARGS rtc_build_tools=false ) endif() if (LINUX AND "$ENV{TARGET_ARCH}" STREQUAL "") message(STATUS ">>> Using system g++") set(CUSTOM_CXX FALSE) else() message(STATUS ">>> Using custom libc++") set(CUSTOM_CXX TRUE) endif() if (WIN32) list(APPEND GN_GEN_ARGS is_clang=false) endif() if (CMAKE_BUILD_TYPE STREQUAL "Debug") list(APPEND GN_GEN_ARGS is_debug=true) else() list(APPEND GN_GEN_ARGS is_debug=false) endif() string(REPLACE ";" " " GN_GEN_ARGS "${GN_GEN_ARGS}") if(WIN32) set(suffix bat) set(PLATFORM windows) else() set(suffix sh) if(APPLE) set(PLATFORM darwin) else() set(PLATFORM linux) endif() endif() if (WIN32) set(byproducts ${libwebrtc_binary_dir}/obj/webrtc.lib ${libwebrtc_binary_dir}/obj/pc/peerconnection.lib ) else() set(byproducts ${libc++_objects} ${libwebrtc_binary_dir}/obj/libwebrtc.a ${libwebrtc_binary_dir}/obj/pc/libpeerconnection.a ) if (NOT APPLE) list(APPEND byproducts ${libc++abi_objects}) endif() endif() ExternalProject_Add( project_libwebrtc PREFIX ${CMAKE_BINARY_DIR}/external/libwebrtc/prefix TMP_DIR ${CMAKE_BINARY_DIR}/external/libwebrtc/tmp STAMP_DIR ${CMAKE_BINARY_DIR}/external/libwebrtc/stamp DOWNLOAD_DIR ${CMAKE_BINARY_DIR}/external/libwebrtc/download SOURCE_DIR ${CMAKE_BINARY_DIR}/external/libwebrtc/download/src BINARY_DIR ${CMAKE_BINARY_DIR}/external/libwebrtc #/build/${CMAKE_BUILD_TYPE} BUILD_BYPRODUCTS /libpeerconnection.a /libwebrtc.a /libc++.a DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND ${CMAKE_COMMAND} -E env CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ${CMAKE_SOURCE_DIR}/scripts/unpack-webrtc.${suffix} ) if (LINUX) # TODO this repeats `scripts/configure-webrtc.sh`; consolidate if (ARM) set(sysroot_flags --arch=arm) elseif (ARM64) set(sysroot_flags --arch=arm64) else() set(sysroot_flags --arch=amd64) endif() ExternalProject_Add( linux_sysroot DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND python2 ${CMAKE_BINARY_DIR}/external/libwebrtc/build/linux/sysroot_scripts/install-sysroot.py ${sysroot_flags} ) add_dependencies(linux_sysroot project_libwebrtc) endif() ExternalProject_Get_Property(project_libwebrtc BINARY_DIR) set(libwebrtc_binary_dir "${BINARY_DIR}") add_library(libc++ STATIC IMPORTED) set_property(TARGET libc++ PROPERTY IMPORTED_LOCATION "${libwebrtc_binary_dir}/libc++.a") add_library(libwebrtc STATIC IMPORTED) add_dependencies(libwebrtc project_libwebrtc) if(WIN32) set_property(TARGET libwebrtc PROPERTY IMPORTED_LOCATION "${libwebrtc_binary_dir}/webrtc.lib") else() set_property(TARGET libwebrtc PROPERTY IMPORTED_LOCATION "${libwebrtc_binary_dir}/libwebrtc.a") endif() add_library(libpeerconnection STATIC IMPORTED) add_dependencies(libpeerconnection project_libwebrtc) if(WIN32) set_property(TARGET libpeerconnection PROPERTY IMPORTED_LOCATION "${libwebrtc_binary_dir}/peerconnection.lib") else() set_property(TARGET libpeerconnection PROPERTY IMPORTED_LOCATION "${libwebrtc_binary_dir}/libpeerconnection.a") endif() set(libc++_include_dir "${libwebrtc_source_dir}/src/buildtools/third_party/libc++/trunk/include") set(libc++abi_include_dir "${libwebrtc_source_dir}/src/buildtools/third_party/libc++abi/trunk/include") # NOTE(mroberts): I would like this to be INTERFACE. # # https://gitlab.kitware.com/cmake/cmake/issues/15052 # # target_include_directories(libwebrtc SYSTEM INTERFACE # ${libwebrtc_source_dir} # ${libwebrtc_source_dir}/webrtc # ${libwebrtc_source_dir}/webrtc/third_party/abseil-cpp # ${libwebrtc_source_dir}/webrtc/third_party/libyuv/include # ) # catch2 # ----------------------------------------------------------------------------- if(CMAKE_BUILD_TYPE STREQUAL "Debug") ExternalProject_Add( project_catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG a1cdff4f188170c5b0aa3d5d217b60d821f237df PREFIX ${CMAKE_BINARY_DIR}/external/catch2/prefix TMP_DIR ${CMAKE_BINARY_DIR}/external/catch2/tmp STAMP_DIR ${CMAKE_BINARY_DIR}/external/catch2/stamp DOWNLOAD_DIR ${CMAKE_BINARY_DIR}/external/catch2/download SOURCE_DIR ${CMAKE_BINARY_DIR}/external/catch2/src BINARY_DIR ${CMAKE_BINARY_DIR}/external/catch2/build CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" ) ExternalProject_Get_Property(project_catch2 SOURCE_DIR) set(catch2_install_dir ${SOURCE_DIR}) endif() # node-webrtc # ----------------------------------------------------------------------------- set(MODULE wrtc) include(${CMAKE_SOURCE_DIR}/NodeJS.cmake) if(DEFINED ENV{npm_config_runtime}) if($ENV{npm_config_runtime} STREQUAL "electron") if(NOT DEFINED ENV{npm_config_target}) message(FATAL_ERROR "npm_config_target must be defined for electron build") endif() list(APPEND nodejs_init_args "VERSION" v$ENV{npm_config_target}) if(NOT DEFINED ENV{npm_config_disturl}) message(FATAL_ERROR "npm_config_disturl must be defined for electron build") endif() list(APPEND nodejs_init_args "URL" $ENV{npm_config_disturl}) if($ENV{npm_config_target} STRLESS "4") list(APPEND nodejs_init_args "NAME" "iojs") endif() endif() endif() nodejs_init(${nodejs_init_args}) file(GLOB_RECURSE MODULE_SRC src/*.cc src/*.h) add_nodejs_module(${MODULE} ${MODULE_SRC}) set_property(TARGET ${MODULE} PROPERTY CXX_STANDARD 14) if(NOT iwyu_path STREQUAL "iwyu_path-NOTFOUND") set_property(TARGET ${MODULE} PROPERTY CXX_INCLUDE_WHAT_YOU_USE ${iwyu_path} -Xiwyu --mapping_file=${CMAKE_SOURCE_DIR}/.iwyu.imp) endif() if(NOT clang_tidy_path STREQUAL "clang_tidy_path-NOTFOUND") set_property(TARGET ${MODULE} PROPERTY CXX_CLANG_TIDY ${clang_tidy_path}) endif() set(node_addon_api_dir ${CMAKE_SOURCE_DIR}/node_modules/node-addon-api) # NOTE(mroberts): Workaround for # # https://gitlab.kitware.com/cmake/cmake/issues/15052 # # is to include all the header files here. target_include_directories(${MODULE} SYSTEM PRIVATE ${node_addon_api_dir}/.. ${CMAKE_BINARY_DIR}/external/libwebrtc ${CMAKE_BINARY_DIR}/external/libwebrtc/webrtc ) if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_dependencies(${MODULE} project_catch2) target_include_directories(${MODULE} SYSTEM PRIVATE ${catch2_install_dir}/single_include ) endif() if(LINUX) add_dependencies(${MODULE} linux_sysroot) endif() target_include_directories(${MODULE} PRIVATE ${CMAKE_SOURCE_DIR} ) target_link_libraries(${MODULE} PRIVATE ${CMAKE_THREAD_LIBS_INIT} libwebrtc ) if(APPLE OR WIN32) target_link_libraries(${MODULE} PRIVATE libpeerconnection ) endif() target_compile_definitions(${MODULE} PRIVATE -DNAPI_VERSION=3 -DUSE_BUILTIN_SW_CODECS ) if(WIN32) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /GR-") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd /GR- -D_HAS_ITERATOR_DEBUGGING=0") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /FORCE:UNRESOLVED") target_link_libraries(${MODULE} PRIVATE dmoguids.lib msdmo.lib secur32.lib winmm.lib wmcodecdspuuid.lib ws2_32.lib ) target_compile_definitions(${MODULE} PRIVATE -D_WINSOCKAPI_ -DINCL_EXTRA_HTON_FUNCTIONS -DNOGDI -DNOMINMAX -DWEBRTC_WIN ) else() target_link_libraries(${MODULE} PRIVATE -lc -lm ) if(CUSTOM_CXX) target_compile_options(${MODULE} PRIVATE -nostdinc++ -nodefaultlibs ) target_link_libraries(${MODULE} PRIVATE libc++ ) else() target_link_options(${MODULE} PRIVATE -static-libstdc++ ) endif() target_compile_options(${MODULE} PRIVATE -fno-rtti -fvisibility=hidden -Wall -Wextra -Wno-missing-field-initializers -Wno-uninitialized -Wno-unused-local-typedefs -Wno-unused-variable -Wno-suggest-override -Wpedantic ) if(APPLE) # actually should be if(clang), but there is no such flag target_compile_options(${MODULE} PRIVATE -Wno-missing-prototypes ) endif() target_compile_definitions(${MODULE} PRIVATE -D_LIBCPP_ABI_UNSTABLE -DWEBRTC_POSIX=1 ) if(CMAKE_BUILD_TYPE STREQUAL "Debug") target_compile_options(${MODULE} PRIVATE -g ) target_compile_definitions(${MODULE} PRIVATE -DDEBUG ) endif() if(APPLE) target_link_libraries(${MODULE} PRIVATE "-framework AppKit" "-framework AVFoundation" ) if ("$ENV{TARGET_ARCH}" STREQUAL "arm64") target_compile_options(${MODULE} PRIVATE -arch arm64 ) target_link_options(${MODULE} PRIVATE -arch arm64 ) endif() target_compile_options(${MODULE} PRIVATE -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-documentation -Wno-exit-time-destructors -Wno-float-conversion -Wno-global-constructors -Wno-padded -Wno-shadow -Wno-shadow-field-in-constructor -Wno-shorten-64-to-32 -Wno-sign-conversion -Wno-thread-safety-negative -Wno-unused-template -Wno-weak-vtables ) target_compile_definitions(${MODULE} PRIVATE -D_LIBCPP_ABI_UNSTABLE -DWEBRTC_MAC -DWEBRTC_IOS ) else() target_compile_definitions(${MODULE} PRIVATE -DWEBRTC_LINUX ) target_compile_options(${MODULE} PRIVATE -fpermissive ) set(linux_src ${CMAKE_BINARY_DIR}/external/libwebrtc/build/linux) #set(linux_src ${CMAKE_SOURCE_DIR}/phase-1/build/external/libwebrtc/download/src/build/linux) if ("$ENV{TARGET_ARCH}" STREQUAL "arm" OR "$ENV{TARGET_ARCH}" STREQUAL "arm64") set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR "$ENV{TARGET_ARCH}") if (NOT "$ENV{ARM_TOOLS_PATH}" STREQUAL "") set(tools $ENV{ARM_TOOLS_PATH}) if (NOT "$ENV{ARM_TOOLS_CLANG}" STREQUAL "") set(tools_clang TRUE) endif() else() # Assume that phase-1 build is present and use Clang from there set(tools ${CMAKE_SOURCE_DIR}/phase-1/build/external/libwebrtc/download/src/third_party/llvm-build/Release+Asserts) set(tools_clang TRUE) endif() set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) if ("$ENV{TARGET_ARCH}" STREQUAL "arm") set(CMAKE_SYSROOT ${linux_src}/debian_sid_arm-sysroot) target_compile_options(${MODULE} PRIVATE -march=armv7-a -mfloat-abi=hard -mtune=generic-armv7-a -mfpu=neon ) set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc) set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++) if (tools_clang) target_compile_options(${MODULE} PRIVATE -target arm-linux-gnueabihf ) target_link_options(${MODULE} PRIVATE -target arm-linux-gnueabihf ) endif() else() set(CMAKE_SYSROOT ${linux_src}/debian_sid_arm64-sysroot) set(CMAKE_C_COMPILER ${tools}/bin/aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER ${tools}/bin/aarch64-linux-gnu-g++) if (tools_clang) target_compile_options(${MODULE} PRIVATE -target arm64-linux-gnu ) target_link_options(${MODULE} PRIVATE -target arm64-linux-gnu ) endif() endif() if (tools_clang) target_link_options(${MODULE} PRIVATE -fuse-ld=lld ) set(CMAKE_C_COMPILER ${tools}/bin/clang) set(CMAKE_CXX_COMPILER ${tools}/bin/clang++) endif() else() target_compile_options(${MODULE} PRIVATE #-B${libwebrtc_source_dir}/src/third_party/binutils/Linux_x64/Release/bin --sysroot=${linux_src}/debian_sid_amd64-sysroot ) endif() endif() endif() # astyle # ----------------------------------------------------------------------------- if(CMAKE_BUILD_TYPE STREQUAL "Debug") list(APPEND ASTYLE_CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}") ExternalProject_Add( astyle GIT_REPOSITORY https://github.com/Bareflank/astyle.git GIT_TAG v1.2 GIT_SHALLOW true CMAKE_ARGS ${ASTYLE_CMAKE_ARGS} PREFIX ${CMAKE_BINARY_DIR}/external/astyle/prefix TMP_DIR ${CMAKE_BINARY_DIR}/external/astyle/tmp STAMP_DIR ${CMAKE_BINARY_DIR}/external/astyle/stamp DOWNLOAD_DIR ${CMAKE_BINARY_DIR}/external/astyle/download SOURCE_DIR ${CMAKE_BINARY_DIR}/external/astyle/src BINARY_DIR ${CMAKE_BINARY_DIR}/external/astyle/build ) list(APPEND ASTYLE_ARGS --style=google --lineend=linux --suffix=none --pad-oper --unpad-paren --align-pointer=type --align-reference=type --indent-preproc-define --indent-switches --indent-col1-comments --keep-one-line-statements --keep-one-line-blocks --pad-header --convert-tabs --min-conditional-indent=0 --indent=spaces=2 --indent-continuation=2 --indent-after-parens --close-templates --add-brackets --break-after-logical ${MODULE_SRC} ) if(NOT WIN32 STREQUAL "1") add_custom_target( format COMMAND ${CMAKE_BINARY_DIR}/bin/astyle ${ASTYLE_ARGS} COMMENT "running astyle" ) else() add_custom_target( format COMMAND ${CMAKE_BINARY_DIR}/bin/astyle.exe ${ASTYLE_ARGS} COMMENT "running astyle" ) endif() endif()