Root build infra, per ADR 0020 as amended in 9624e68: PORT owns the per-OS
backend directories and macOS/Windows packaging, but cmake/platform*.cmake stays
PKG/QA's — the amendment exists because Phase 0 (CORE's and DAEMON's own seams,
on Linux) needs velox_platform_sources() to select platform/linux/*.cpp, and PORT
can't start until Phase 0 lands. Landing it as PORT-owned would have deadlocked
both lanes waiting on each other.
cmake/platform.cmake sets exactly one of VELOX_OS_LINUX/VELOX_OS_MACOS/
VELOX_OS_WINDOWS from CMAKE_SYSTEM_NAME and exposes velox_platform_sources(target
dir), which globs dir/platform/<os>/*.cpp. No seam consumes it yet (Phase 0 hasn't
landed), so on Ubuntu this changes nothing observable — VELOX_OS_LINUX is simply
true and no lane calls the new function.
pkg_check_modules(LIBSECRET ...) was unconditional in the root CMakeLists.txt,
so macOS could not configure at all (docs/08-porting.md's stated blocker); it's
now gated on VELOX_OS_LINUX, same as the Qt6::DBus component this also adds
(gui/docs/pkg-qa-requests-m1.md R4 — backs the org.freedesktop.portal
GlobalShortcuts path, which is Linux/portal-only same as libsecret). Both are
still REQUIRED on Linux; PORT adds the macOS sides (Keychain, and no DBus
equivalent needed) behind their own seams, not by touching this find.
Verified: fresh configure + build of veloxd/velox/velox-gui/velox-nmhost still
green (libsecret-1 and Qt6::DBus both found), the .deb from the previous commit
still builds and installs.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_0176u3fTrxegrGNm2yC7r69W
184 lines
7.9 KiB
CMake
184 lines
7.9 KiB
CMake
# Velox Download Manager — top-level build. Owned by lane PKG/QA.
|
|
#
|
|
# Lanes land in parallel and merge to main independently, so every add_subdirectory()
|
|
# here is guarded by EXISTS on the lane's own CMakeLists.txt: main always configures,
|
|
# and a lane's targets light up the moment that lane merges — no coordinated edit here.
|
|
#
|
|
# cmake --preset dev && cmake --build --preset dev
|
|
# ctest --preset dev
|
|
|
|
cmake_minimum_required(VERSION 3.28)
|
|
|
|
project(velox
|
|
VERSION 0.1.0
|
|
DESCRIPTION "IDM-class download manager for Linux"
|
|
LANGUAGES CXX)
|
|
|
|
set(CMAKE_CXX_STANDARD 23)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
|
|
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
|
endif()
|
|
|
|
option(VELOX_BUILD_GUI "Build the Qt 6 GUI client" ON)
|
|
option(VELOX_BUILD_TESTS "Build unit and integration tests" ON)
|
|
option(VELOX_BUILD_FUZZ "Build libFuzzer targets (clang only)" OFF)
|
|
option(VELOX_ENABLE_MEDIA "Build the HLS/DASH media grabber (M4)" OFF)
|
|
option(VELOX_WERROR "Treat warnings as errors" ON)
|
|
|
|
# Central OS detection (docs/adr/0020-cross-platform-strategy.md). Included early: the
|
|
# dependency finds below gate Linux-only libraries on VELOX_OS_LINUX.
|
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/platform.cmake)
|
|
|
|
# Project-wide warning flags. Set via add_compile_options (a directory property), not the
|
|
# CMAKE_CXX_FLAGS cache variable, because the dev/tsan presets overwrite that cache var
|
|
# wholesale for sanitizer flags — a target's warnings must not ride on it.
|
|
add_compile_options(-Wall -Wextra -Wpedantic)
|
|
if(VELOX_WERROR)
|
|
add_compile_options(-Werror)
|
|
endif()
|
|
|
|
if(VELOX_BUILD_FUZZ AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
message(WARNING "VELOX_BUILD_FUZZ is ON but the compiler is ${CMAKE_CXX_COMPILER_ID}; "
|
|
"libFuzzer needs Clang. Fuzz targets will be skipped.")
|
|
endif()
|
|
|
|
# --- Dependencies -------------------------------------------------------------------
|
|
# Found once here so a missing -dev package fails at configure with a clear name, rather
|
|
# than deep in a lane. Each find is gated on the lane that needs it being present.
|
|
find_package(Threads REQUIRED)
|
|
|
|
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/core/CMakeLists.txt)
|
|
find_package(CURL 8.0 REQUIRED)
|
|
find_package(OpenSSL REQUIRED)
|
|
endif()
|
|
|
|
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/daemon/CMakeLists.txt)
|
|
find_package(SQLite3 REQUIRED)
|
|
find_package(nlohmann_json 3.11 REQUIRED)
|
|
# libsecret / Secret Service is Linux-only (docs/adr/0020-cross-platform-strategy.md,
|
|
# docs/08-porting.md): macOS uses Keychain behind the same credential-store seam, so
|
|
# this stays REQUIRED on Linux and simply absent elsewhere — PORT's job is to add the
|
|
# macOS side of that seam, not to touch this find.
|
|
if(VELOX_OS_LINUX)
|
|
find_package(PkgConfig REQUIRED)
|
|
pkg_check_modules(LIBSECRET REQUIRED IMPORTED_TARGET libsecret-1)
|
|
endif()
|
|
endif()
|
|
|
|
if(VELOX_BUILD_GUI AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/gui/CMakeLists.txt)
|
|
# DBus (gui/docs/pkg-qa-requests-m1.md R4) backs the org.freedesktop.portal
|
|
# GlobalShortcuts path — Linux/portal-only, same reasoning as libsecret above.
|
|
if(VELOX_OS_LINUX)
|
|
find_package(Qt6 6.6 REQUIRED COMPONENTS Widgets Svg Network DBus LinguistTools)
|
|
else()
|
|
find_package(Qt6 6.6 REQUIRED COMPONENTS Widgets Svg Network LinguistTools)
|
|
endif()
|
|
qt_standard_project_setup()
|
|
endif()
|
|
|
|
if(VELOX_ENABLE_MEDIA)
|
|
find_package(PkgConfig REQUIRED)
|
|
pkg_check_modules(FFMPEG REQUIRED IMPORTED_TARGET
|
|
libavformat libavcodec libavutil)
|
|
endif()
|
|
|
|
# --- Tests --------------------------------------------------------------------------
|
|
if(VELOX_BUILD_TESTS)
|
|
enable_testing()
|
|
endif()
|
|
|
|
# --- Lane targets (guarded; see header) -------------------------------------------
|
|
foreach(lane IN ITEMS core daemon cli nmhost)
|
|
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${lane}/CMakeLists.txt)
|
|
add_subdirectory(${lane})
|
|
else()
|
|
message(STATUS "velox: lane '${lane}' has not landed a CMakeLists yet — skipping.")
|
|
endif()
|
|
endforeach()
|
|
|
|
if(VELOX_BUILD_GUI)
|
|
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/gui/CMakeLists.txt)
|
|
add_subdirectory(gui)
|
|
else()
|
|
message(STATUS "velox: lane 'gui' has not landed a CMakeLists yet — skipping.")
|
|
endif()
|
|
endif()
|
|
|
|
foreach(toolset tools/testserver tools/bench tools/fuzz tools/mockd)
|
|
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${toolset}/CMakeLists.txt)
|
|
add_subdirectory(${toolset})
|
|
endif()
|
|
endforeach()
|
|
|
|
if(VELOX_BUILD_TESTS)
|
|
foreach(suite tests/conformance tests/integration tests/e2e)
|
|
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${suite}/CMakeLists.txt)
|
|
add_subdirectory(${suite})
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
|
|
# --- Install rules (M6 packaging; docs/07-packaging.md; owned by PKG/QA) ------------
|
|
#
|
|
# Guarded by `if(TARGET ...)`, not by editing each lane's own CMakeLists.txt: install()
|
|
# is a packaging concern, and reaching into daemon/CMakeLists.txt (DAEMON's), cli's build
|
|
# file (also DAEMON's) or gui/CMakeLists.txt (GUI's) to add it there would cross a lane
|
|
# boundary CLAUDE.md draws on purpose. Every target below is defined by its own lane;
|
|
# this only says where the packaged binary already built by that lane's rules goes.
|
|
#
|
|
# libveloxcore is intentionally absent here: it stays a static library linked into each
|
|
# binary (user decision, see docs/07-packaging.md) — there is no .so to install.
|
|
#
|
|
# CMAKE_INSTALL_LIBDIR is multiarch-adjusted (lib/x86_64-linux-gnu/) by GNUInstallDirs on
|
|
# Debian; systemd user units and the Mozilla native-messaging directory are NOT
|
|
# architecture-specific paths, so those two destinations are written literally
|
|
# (lib/systemd/user, lib/mozilla/...) rather than built from that variable.
|
|
include(GNUInstallDirs)
|
|
|
|
if(TARGET veloxd)
|
|
install(TARGETS veloxd RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
install(FILES ${CMAKE_SOURCE_DIR}/packaging/man/veloxd.8
|
|
DESTINATION ${CMAKE_INSTALL_MANDIR}/man8)
|
|
# velox.socket ships alongside velox.service: DAEMON wired real sd_listen_fds()
|
|
# socket activation (daemon/src/rpc/systemd_activation.cpp) — see
|
|
# packaging/systemd/README.md for the pair's own rationale.
|
|
install(FILES ${CMAKE_SOURCE_DIR}/packaging/systemd/velox.service
|
|
${CMAKE_SOURCE_DIR}/packaging/systemd/velox.socket
|
|
DESTINATION lib/systemd/user)
|
|
endif()
|
|
|
|
if(TARGET velox)
|
|
install(TARGETS velox RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
# DAEMON owns cli/ and its man page (CLAUDE.md); packaging only installs it.
|
|
install(FILES ${CMAKE_SOURCE_DIR}/cli/man/velox.1
|
|
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
|
endif()
|
|
|
|
if(TARGET velox-gui)
|
|
install(TARGETS velox-gui RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
install(FILES ${CMAKE_SOURCE_DIR}/packaging/man/velox-gui.1
|
|
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
|
install(FILES ${CMAKE_SOURCE_DIR}/packaging/desktop/velox.desktop
|
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
|
foreach(iconsize 16 22 24 32 48 64 128 256)
|
|
install(FILES
|
|
${CMAKE_SOURCE_DIR}/packaging/icons/hicolor/${iconsize}x${iconsize}/apps/velox.png
|
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/${iconsize}x${iconsize}/apps)
|
|
endforeach()
|
|
endif()
|
|
|
|
# nmhost and its manifest are DAEMON's (CLAUDE.md: nmhost/ and packaging/nativehost/).
|
|
# This lights up the moment DAEMON's target exists, the same way the add_subdirectory()
|
|
# guards above do — no coordinated edit needed when it lands.
|
|
if(TARGET velox-nmhost)
|
|
install(TARGETS velox-nmhost RUNTIME DESTINATION libexec/velox)
|
|
install(FILES ${CMAKE_SOURCE_DIR}/packaging/nativehost/com.velox.host.json
|
|
DESTINATION lib/mozilla/native-messaging-hosts)
|
|
else()
|
|
message(STATUS "velox: nmhost has not landed yet — native-messaging manifest not installed.")
|
|
endif()
|