mirror of
https://github.com/lux-tel/libsession-util.git
synced 2026-10-30 20:25:11 +00:00
When we load oxen-logging via system lib, the code that was supposed to also inject fmt/spdlog with it was not working properly because the "did we go via submodule" was falsely returning true. This fixes it by using an intermediate library so that we can properly distinguish between the cases (final oxen::logging exists - submodule, which already gives fmt/spdlog; otherwise use the intermediate target and set final oxen::logging alias manually). This also fixes the default STATIC_BUNDLE to depend on BUILD_STATIC_DEPS, rather than NOT BUILD_SHARED_LIBS, so that -DBUILD_STATIC_DEPS=OFF doesn't accidentally default to attempting a static bundle without static deps. (That case is also now detected and becomes a fatal error).
234 lines
10 KiB
CMake
234 lines
10 KiB
CMake
option(SUBMODULE_CHECK "Enables checking that vendored library submodules are up to date" ON)
|
|
|
|
if(SUBMODULE_CHECK)
|
|
find_package(Git)
|
|
if(GIT_FOUND)
|
|
function(check_submodule relative_path)
|
|
execute_process(COMMAND git rev-parse "HEAD" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${relative_path} OUTPUT_VARIABLE localHead)
|
|
execute_process(COMMAND git rev-parse "HEAD:external/${relative_path}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE checkedHead)
|
|
string(COMPARE EQUAL "${localHead}" "${checkedHead}" upToDate)
|
|
if (upToDate)
|
|
message(STATUS "Submodule 'external/${relative_path}' is up-to-date")
|
|
else()
|
|
message(FATAL_ERROR "Submodule 'external/${relative_path}' is not up-to-date. Please update with\ngit submodule update --init --recursive\nor run cmake with -DSUBMODULE_CHECK=OFF")
|
|
endif()
|
|
|
|
# Extra arguments check nested submodules
|
|
foreach(submod ${ARGN})
|
|
execute_process(COMMAND git rev-parse "HEAD" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${relative_path}/${submod} OUTPUT_VARIABLE localHead)
|
|
execute_process(COMMAND git rev-parse "HEAD:${submod}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${relative_path} OUTPUT_VARIABLE checkedHead)
|
|
string(COMPARE EQUAL "${localHead}" "${checkedHead}" upToDate)
|
|
if (NOT upToDate)
|
|
message(FATAL_ERROR "Nested submodule '${relative_path}/${submod}' is not up-to-date. Please update with\ngit submodule update --init --recursive\nor run cmake with -DSUBMODULE_CHECK=OFF")
|
|
endif()
|
|
endforeach()
|
|
endfunction ()
|
|
|
|
message(STATUS "Checking submodules")
|
|
check_submodule(ios-cmake)
|
|
check_submodule(libsodium-internal)
|
|
check_submodule(zstd)
|
|
check_submodule(protobuf)
|
|
check_submodule(session-router)
|
|
check_submodule(date)
|
|
endif()
|
|
endif()
|
|
|
|
if(NOT BUILD_STATIC_DEPS AND NOT FORCE_ALL_SUBMODULES)
|
|
find_package(PkgConfig REQUIRED)
|
|
endif()
|
|
|
|
macro(libsession_system_or_submodule BIGNAME smallname target pkgconf subdir)
|
|
if(NOT TARGET ${target})
|
|
option(FORCE_${BIGNAME}_SUBMODULE "force using ${smallname} submodule" OFF)
|
|
if(NOT BUILD_STATIC_DEPS AND NOT FORCE_${BIGNAME}_SUBMODULE AND NOT FORCE_ALL_SUBMODULES)
|
|
pkg_check_modules(${BIGNAME} ${pkgconf} IMPORTED_TARGET GLOBAL)
|
|
endif()
|
|
if(${BIGNAME}_FOUND)
|
|
add_library(${smallname} INTERFACE IMPORTED GLOBAL)
|
|
if(NOT TARGET PkgConfig::${BIGNAME} AND CMAKE_VERSION VERSION_LESS "3.21")
|
|
# Work around cmake bug 22180 (PkgConfig::THING not set if no flags needed)
|
|
else()
|
|
target_link_libraries(${smallname} INTERFACE PkgConfig::${BIGNAME})
|
|
endif()
|
|
message(STATUS "Found system ${smallname} ${${BIGNAME}_VERSION}")
|
|
else()
|
|
message(STATUS "using ${smallname} submodule ${subdir}")
|
|
add_subdirectory(${subdir})
|
|
endif()
|
|
if(NOT TARGET ${target})
|
|
add_library(${target} ALIAS ${smallname})
|
|
endif()
|
|
if(BUILD_STATIC_DEPS AND STATIC_BUNDLE)
|
|
libsession_static_bundle(${smallname}::${smallname})
|
|
endif()
|
|
endif()
|
|
endmacro()
|
|
|
|
|
|
set(deps_cc "${CMAKE_C_COMPILER}")
|
|
set(cross_host "")
|
|
set(cross_rc "")
|
|
if(CMAKE_CROSSCOMPILING)
|
|
if(APPLE_TARGET_TRIPLE)
|
|
set(cross_host "--host=${APPLE_TARGET_TRIPLE}")
|
|
elseif(ANDROID)
|
|
if(CMAKE_ANDROID_ARCH_ABI MATCHES x86_64)
|
|
set(cross_host "--host=x86_64-linux-android")
|
|
set(android_compiler_prefix x86_64)
|
|
set(android_compiler_suffix linux-android)
|
|
elseif(CMAKE_ANDROID_ARCH_ABI MATCHES x86)
|
|
set(cross_host "--host=i686-linux-android")
|
|
set(android_compiler_prefix i686)
|
|
set(android_compiler_suffix linux-android)
|
|
elseif(CMAKE_ANDROID_ARCH_ABI MATCHES armeabi-v7a)
|
|
set(cross_host "--host=armv7a-linux-androideabi")
|
|
set(android_compiler_prefix armv7a)
|
|
set(android_compiler_suffix linux-androideabi)
|
|
elseif(CMAKE_ANDROID_ARCH_ABI MATCHES arm64-v8a)
|
|
set(cross_host "--host=aarch64-linux-android")
|
|
set(android_compiler_prefix aarch64)
|
|
set(android_compiler_suffix linux-android)
|
|
else()
|
|
message(FATAL_ERROR "unknown android arch: ${CMAKE_ANDROID_ARCH_ABI}")
|
|
endif()
|
|
|
|
string(REPLACE "android-" "" android_platform_num "${ANDROID_PLATFORM}")
|
|
set(deps_cc "${ANDROID_TOOLCHAIN_ROOT}/bin/${android_compiler_prefix}-${android_compiler_suffix}${android_platform_num}-clang")
|
|
else()
|
|
set(cross_host "--host=${ARCH_TRIPLET}")
|
|
if (ARCH_TRIPLET MATCHES mingw AND CMAKE_RC_COMPILER)
|
|
set(cross_rc "WINDRES=${CMAKE_RC_COMPILER}")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
if(ENABLE_NETWORKING)
|
|
set(LIBQUIC_BUILD_TESTS OFF CACHE BOOL "")
|
|
libsession_system_or_submodule(OXENQUIC quic oxen::quic liboxenquic>=1.8 session-router/external/oxen-libquic)
|
|
endif()
|
|
|
|
libsession_system_or_submodule(OXENC oxenc oxenc::oxenc liboxenc>=1.5.0 session-router/external/oxen-libquic/external/oxen-encoding)
|
|
|
|
if(NOT TARGET oxen::logging)
|
|
# Find this one using an intermediate target alias (oxenlogging::oxenlogging) rather than the
|
|
# final oxen::logging alias target that we actually use: that way either we go into using it as
|
|
# a submodule (in which case the submodule sets up oxen::logging), or else we find via system
|
|
# lib, in which case we need an extra intermediate interface library that also brings in fmt and
|
|
# spdlog.
|
|
libsession_system_or_submodule(OXENLOGGING oxen-logging oxenlogging::oxenlogging liboxen-logging>=1.2.0 session-router/external/oxen-libquic/external/oxen-logging)
|
|
if(NOT TARGET oxen::logging)
|
|
# If we load oxen-logging via system lib then we won't necessarily have fmt/spdlog targets,
|
|
# but this script will give us them:
|
|
include(session-router/external/oxen-libquic/external/oxen-logging/cmake/load_fmt_spdlog.cmake)
|
|
|
|
add_library(oxen-logging-fmt-spdlog INTERFACE)
|
|
target_link_libraries(oxen-logging-fmt-spdlog INTERFACE oxenlogging::oxenlogging ${OXEN_LOGGING_FMT_TARGET} ${OXEN_LOGGING_SPDLOG_TARGET})
|
|
add_library(oxen::logging ALIAS oxen-logging-fmt-spdlog)
|
|
endif()
|
|
endif()
|
|
|
|
|
|
|
|
if(CMAKE_C_COMPILER_LAUNCHER)
|
|
set(deps_cc "${CMAKE_C_COMPILER_LAUNCHER} ${deps_cc}")
|
|
endif()
|
|
set(deps_CFLAGS "-O2")
|
|
|
|
if(IPO_ENABLED)
|
|
set(deps_CFLAGS "${deps_CFLAGS} -flto")
|
|
endif()
|
|
|
|
if(APPLE)
|
|
foreach(lang C CXX)
|
|
string(APPEND deps_${lang}FLAGS " ${CMAKE_${lang}_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT} ${CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
|
foreach(arch ${CMAKE_OSX_ARCHITECTURES})
|
|
string(APPEND deps_${lang}FLAGS " -arch ${arch}")
|
|
endforeach()
|
|
endforeach()
|
|
endif()
|
|
|
|
function(add_static_subdirectory dir)
|
|
set(BUILD_SHARED_LIBS OFF)
|
|
add_subdirectory(${dir} ${ARGN})
|
|
endfunction()
|
|
|
|
add_static_subdirectory(libsodium-internal)
|
|
libsession_static_bundle(libsodium::sodium-internal)
|
|
|
|
|
|
set(protobuf_VERBOSE ON CACHE BOOL "" FORCE)
|
|
set(protobuf_INSTALL ON CACHE BOOL "" FORCE)
|
|
set(protobuf_WITH_ZLIB OFF CACHE BOOL "" FORCE)
|
|
set(protobuf_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
|
set(protobuf_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
|
set(protobuf_BUILD_LIBPROTOC OFF CACHE BOOL "" FORCE)
|
|
set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
|
set(protobuf_ABSL_PROVIDER "module" CACHE STRING "" FORCE)
|
|
set(protobuf_BUILD_PROTOC_BINARIES OFF CACHE BOOL "")
|
|
set(protobuf_BUILD_PROTOBUF_BINARIES ON CACHE BOOL "" FORCE)
|
|
libsession_system_or_submodule(PROTOBUF_LITE protobuf_lite protobuf::libprotobuf-lite protobuf-lite>=3.21 protobuf)
|
|
if(TARGET PkgConfig::PROTOBUF_LITE AND NOT TARGET protobuf::libprotobuf-lite)
|
|
add_library(protobuf::libprotobuf-lite ALIAS PkgConfig::PROTOBUF_LITE)
|
|
endif()
|
|
|
|
|
|
set(ZSTD_BUILD_PROGRAMS OFF CACHE BOOL "")
|
|
set(ZSTD_BUILD_TESTS OFF CACHE BOOL "")
|
|
set(ZSTD_BUILD_CONTRIB OFF CACHE BOOL "")
|
|
set(ZSTD_BUILD_SHARED OFF CACHE BOOL "")
|
|
set(ZSTD_BUILD_STATIC ON CACHE BOOL "")
|
|
set(ZSTD_MULTITHREAD_SUPPORT OFF CACHE BOOL "")
|
|
add_subdirectory(zstd/build/cmake EXCLUDE_FROM_ALL)
|
|
# zstd's cmake doesn't properly set up include paths on its targets, so we have to wrap it in an
|
|
# interface target that does:
|
|
add_library(libzstd_static_fixed_includes INTERFACE)
|
|
target_include_directories(libzstd_static_fixed_includes INTERFACE zstd/lib zstd/lib/common)
|
|
target_link_libraries(libzstd_static_fixed_includes INTERFACE libzstd_static)
|
|
add_library(libzstd::static ALIAS libzstd_static_fixed_includes)
|
|
export(
|
|
TARGETS libzstd_static_fixed_includes
|
|
NAMESPACE libsession::
|
|
FILE libsessionZstd.cmake
|
|
)
|
|
libsession_static_bundle(libzstd_static)
|
|
|
|
|
|
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
|
set(JSON_Install ON CACHE INTERNAL "") # Required to export targets that we use
|
|
libsession_system_or_submodule(NLOHMANN nlohmann_json nlohmann_json::nlohmann_json nlohmann_json>=3.7.0 session-router/external/nlohmann)
|
|
|
|
if(ENABLE_NETWORKING AND ENABLE_NETWORKING_SROUTER)
|
|
set(SROUTER_FULL OFF CACHE BOOL "")
|
|
set(SROUTER_DAEMON OFF CACHE BOOL "")
|
|
set(SROUTER_NATIVE_BUILD OFF CACHE BOOL "")
|
|
set(SROUTER_JEMALLOC OFF CACHE BOOL "")
|
|
|
|
add_library(sodium INTERFACE)
|
|
target_link_libraries(sodium INTERFACE libsodium::sodium-internal)
|
|
add_static_subdirectory(session-router EXCLUDE_FROM_ALL)
|
|
libsession_static_bundle(session-router::libsessionrouter)
|
|
endif()
|
|
|
|
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
|
set(JSON_Install ON CACHE INTERNAL "") # Required to export targets that we use
|
|
|
|
function(simdutf_subdir)
|
|
set(SIMDUTF_TESTS OFF CACHE BOOL "")
|
|
set(SIMDUTF_TOOLS OFF CACHE BOOL "")
|
|
set(BUILD_SHARED_LIBS OFF)
|
|
add_subdirectory(simdutf)
|
|
endfunction()
|
|
simdutf_subdir()
|
|
libsession_static_bundle(simdutf)
|
|
|
|
# We need Howard Hinnant's header-only date library for now because the STL implementation of
|
|
# std::chrono::parse() is spotty or broken on:
|
|
# - Apple. libc++ date parsing is only available when on XCode 16.3+ *and* targetting macOS 15+.
|
|
# - gcc before 13.
|
|
# - clang+libc++ before llvm-19. (Real 19, not Apple's idiotic PR renumbering).
|
|
#
|
|
# On the plus side, this is header-only so we don't actually compile anything extra if we don't
|
|
# actually use it.
|
|
add_subdirectory(date)
|