include(ExternalProject) function(lg_add_static_msquic) if(TARGET msquic::msquic) return() endif() if(NOT WIN32) message(FATAL_ERROR "The in-tree static MsQuic target is only available on Windows") endif() if(CMAKE_VERSION VERSION_LESS 3.20) message(FATAL_ERROR "The in-tree static MsQuic target requires CMake 3.20 or newer") endif() set(LG_MSQUIC_SOURCE_DIR "${PROJECT_TOP}/repos/MsQuic") set(LG_MSQUIC_BINARY_DIR "${CMAKE_BINARY_DIR}/MsQuic") set(LG_MSQUIC_SYSTEM_LIBRARIES ws2_32 schannel secur32 onecore wbemuuid winmm ntdll bcrypt ncrypt crypt32 iphlpapi advapi32 ) set(LG_MSQUIC_CMAKE_ARGS "-DQUIC_BUILD_SHARED=OFF" "-DQUIC_BUILD_TOOLS=OFF" "-DQUIC_BUILD_TEST=OFF" "-DQUIC_BUILD_PERF=OFF" "-DQUIC_TLS_LIB=schannel" "-DQUIC_ENABLE_LOGGING=OFF" "-DQUIC_STATIC_LINK_CRT=OFF" "-DQUIC_STATIC_LINK_PARTIAL_CRT=OFF" "-DQUIC_SOURCE_LINK=OFF" "-DQUIC_PDBALTPATH=OFF" "-DQUIC_EMBED_GIT_HASH=OFF" ) if(NOT EXISTS "${LG_MSQUIC_SOURCE_DIR}/CMakeLists.txt") message(FATAL_ERROR "The MsQuic submodule is not initialized; run " "git submodule update --init --recursive") endif() if(MSVC) set(LG_MSQUIC_DEBUG_LIBRARY "${LG_MSQUIC_BINARY_DIR}/bin/Debug/msquic.lib") set(LG_MSQUIC_BUILD_CONFIG "$") set(LG_MSQUIC_BUILD_COMMAND "${CMAKE_COMMAND}" --build --config ${LG_MSQUIC_BUILD_CONFIG} --target msquic_lib --parallel ) elseif(MINGW) if(NOT MINGW64_TRIPLE) set(MINGW64_TRIPLE x86_64-w64-mingw32) endif() if(CMAKE_FIND_ROOT_PATH) list(GET CMAKE_FIND_ROOT_PATH 0 LG_MSQUIC_MINGW_ROOT) else() set(LG_MSQUIC_MINGW_ROOT "/usr/${MINGW64_TRIPLE}") endif() set(LG_MSQUIC_DEBUG_LIBRARY "${LG_MSQUIC_BINARY_DIR}/bin/Release/msquic.lib") find_program(LG_MSQUIC_CLANG_CL clang-cl REQUIRED) find_program(LG_MSQUIC_LLVM_LIB llvm-lib REQUIRED) find_program(LG_MSQUIC_MINGW_GCC NAMES "${MINGW64_TRIPLE}-gcc" x86_64-w64-mingw32-gcc REQUIRED) find_program(LG_MSQUIC_WINDRES NAMES "${MINGW64_TRIPLE}-windres" x86_64-w64-mingw32-windres REQUIRED) # MsQuic's Windows sources use the CL command-line ABI and its monolithic # archive rule uses lib.exe syntax. Compile those sources with clang-cl, # while targeting the same MinGW-w64 ABI and import libraries as the # surrounding client build. set(LG_MSQUIC_IMPORT_DIR "${LG_MSQUIC_BINARY_DIR}/mingw-imports") file(MAKE_DIRECTORY "${LG_MSQUIC_IMPORT_DIR}") foreach(LG_MSQUIC_SYSTEM_LIBRARY onecore secur32 wbemuuid winmm) string(TOUPPER "${LG_MSQUIC_SYSTEM_LIBRARY}" LG_MSQUIC_SYSTEM_LIBRARY_UPPER) find_library(LG_MSQUIC_${LG_MSQUIC_SYSTEM_LIBRARY_UPPER}_LIBRARY NAMES "${LG_MSQUIC_SYSTEM_LIBRARY}" PATHS "${LG_MSQUIC_MINGW_ROOT}/lib" NO_DEFAULT_PATH REQUIRED) configure_file( "${LG_MSQUIC_${LG_MSQUIC_SYSTEM_LIBRARY_UPPER}_LIBRARY}" "${LG_MSQUIC_IMPORT_DIR}/${LG_MSQUIC_SYSTEM_LIBRARY}.lib" COPYONLY) endforeach() list(APPEND LG_MSQUIC_CMAKE_ARGS "-DCMAKE_BUILD_TYPE=RelWithDebInfo" "-DCMAKE_TOOLCHAIN_FILE=${PROJECT_TOP}/cmake/toolchains/msquic-clangcl-mingw64.cmake" "-DMSQUIC_MINGW_TRIPLE=${MINGW64_TRIPLE}" "-DMSQUIC_MINGW_ROOT=${LG_MSQUIC_MINGW_ROOT}" "-DMSQUIC_CLANG_CL=${LG_MSQUIC_CLANG_CL}" "-DMSQUIC_LLVM_LIB=${LG_MSQUIC_LLVM_LIB}" "-DMSQUIC_MINGW_GCC=${LG_MSQUIC_MINGW_GCC}" "-DMSQUIC_WINDRES=${LG_MSQUIC_WINDRES}" "-DHAS_SPECTRE=OFF" "-DHAS_GUARDCF=OFF" ) set(LG_MSQUIC_BUILD_COMMAND "${CMAKE_COMMAND}" -E env "LIB=${LG_MSQUIC_IMPORT_DIR}" "${CMAKE_COMMAND}" --build --target msquic_lib --parallel ) else() message(FATAL_ERROR "Static MsQuic on Windows requires MSVC or the MinGW-w64 " "clang-cl cross-build toolchain") endif() ExternalProject_Add(lg_msquic_build SOURCE_DIR "${LG_MSQUIC_SOURCE_DIR}" BINARY_DIR "${LG_MSQUIC_BINARY_DIR}" DOWNLOAD_COMMAND "" UPDATE_COMMAND "" INSTALL_COMMAND "" CMAKE_ARGS ${LG_MSQUIC_CMAKE_ARGS} BUILD_COMMAND ${LG_MSQUIC_BUILD_COMMAND} BUILD_BYPRODUCTS "${LG_MSQUIC_BINARY_DIR}/bin/Debug/msquic.lib" "${LG_MSQUIC_BINARY_DIR}/bin/Release/msquic.lib" ) add_library(lg_msquic STATIC IMPORTED GLOBAL) set_target_properties(lg_msquic PROPERTIES IMPORTED_CONFIGURATIONS "Debug;Release;RelWithDebInfo;MinSizeRel" IMPORTED_LOCATION_DEBUG "${LG_MSQUIC_DEBUG_LIBRARY}" IMPORTED_LOCATION_RELEASE "${LG_MSQUIC_BINARY_DIR}/bin/Release/msquic.lib" IMPORTED_LOCATION_RELWITHDEBINFO "${LG_MSQUIC_BINARY_DIR}/bin/Release/msquic.lib" IMPORTED_LOCATION_MINSIZEREL "${LG_MSQUIC_BINARY_DIR}/bin/Release/msquic.lib" INTERFACE_COMPILE_DEFINITIONS QUIC_BUILD_STATIC INTERFACE_INCLUDE_DIRECTORIES "${LG_MSQUIC_SOURCE_DIR}/src/inc" INTERFACE_LINK_LIBRARIES "${LG_MSQUIC_SYSTEM_LIBRARIES}" ) add_dependencies(lg_msquic lg_msquic_build) add_library(msquic::msquic ALIAS lg_msquic) endfunction()