Files
2026-10-29 13:36:44 +00:00

130 lines
6.3 KiB
CMake

cmake_minimum_required(VERSION 3.22)
project(rockstream VERSION 0.1.0 LANGUAGES CXX)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
message(FATAL_ERROR "rockstream currently supports Linux only")
endif()
option(ROCKSTREAM_WITH_MPP "Build with the target BSP's Rockchip MPP SDK" OFF)
option(ROCKSTREAM_SANITIZERS "Enable AddressSanitizer and UndefinedBehaviorSanitizer" OFF)
option(ROCKSTREAM_WARNINGS_AS_ERRORS "Treat project compiler warnings as errors" OFF)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CTest)
include(GNUInstallDirs)
find_package(Threads REQUIRED)
add_library(rockstream_options INTERFACE)
target_compile_features(rockstream_options INTERFACE cxx_std_20)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(rockstream_options INTERFACE
-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wshadow
$<$<BOOL:${ROCKSTREAM_WARNINGS_AS_ERRORS}>:-Werror>)
if(ROCKSTREAM_SANITIZERS)
include(CheckCXXSourceCompiles)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_FLAGS "-fsanitize=address,undefined")
set(CMAKE_REQUIRED_LINK_OPTIONS "-fsanitize=address,undefined")
check_cxx_source_compiles("int main() { return 0; }" ROCKSTREAM_SANITIZERS_LINK)
cmake_pop_check_state()
if(NOT ROCKSTREAM_SANITIZERS_LINK)
message(FATAL_ERROR "Sanitizer runtime compile/link check failed. Install ASan and UBSan runtimes matching your compiler, or disable ROCKSTREAM_SANITIZERS.")
endif()
target_compile_options(rockstream_options INTERFACE
-fsanitize=address,undefined -fno-omit-frame-pointer)
target_link_options(rockstream_options INTERFACE -fsanitize=address,undefined)
endif()
elseif(ROCKSTREAM_SANITIZERS OR ROCKSTREAM_WARNINGS_AS_ERRORS)
message(FATAL_ERROR "Requested compiler options require GCC or Clang")
endif()
if(ROCKSTREAM_WITH_MPP)
find_package(RockchipMPP REQUIRED)
# Compile and link only: this check never executes hardware code, including
# when cross compiling. Catch missing public headers or an unusable library.
include(CheckCXXSourceCompiles)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_LIBRARIES RockchipMPP::MPP)
unset(ROCKSTREAM_MPP_SDK_LINKS CACHE)
check_cxx_source_compiles("
#include <rk_mpi.h>
#include <mpp_buffer.h>
#include <mpp_frame.h>
#include <mpp_packet.h>
#include <rk_venc_cfg.h>
#include <rk_venc_rc.h>
int main() {
MppCtx ctx = nullptr;
MppApi* api = nullptr;
MppEncCfg cfg = nullptr;
if (mpp_enc_cfg_init(&cfg) != MPP_OK) return 1;
mpp_enc_cfg_deinit(cfg);
if (mpp_create(&ctx, &api) != MPP_OK) return 1;
return mpp_destroy(ctx);
}" ROCKSTREAM_MPP_SDK_LINKS)
cmake_pop_check_state()
if(NOT ROCKSTREAM_MPP_SDK_LINKS)
message(FATAL_ERROR "MPP SDK compile/link check failed. Use matching BSP headers and libraries; see CMakeFiles/CMakeError.log or CMakeConfigureLog.yaml.")
endif()
endif()
configure_file(cmake/build_config.hpp.in generated/rockstream/build_config.hpp @ONLY)
add_library(rockstream_core STATIC src/build_info.cpp src/probe.cpp src/latency.cpp)
target_include_directories(rockstream_core PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_BINARY_DIR}/generated")
target_link_libraries(rockstream_core PRIVATE rockstream_options PUBLIC Threads::Threads)
set_target_properties(rockstream_core PROPERTIES CXX_EXTENSIONS OFF)
if(ROCKSTREAM_WITH_MPP)
target_sources(rockstream_core PRIVATE src/mpp_probe.cpp)
target_link_libraries(rockstream_core PRIVATE RockchipMPP::MPP)
else()
# Host development gets public API declarations, never a pretend MPP runtime.
add_library(rockstream_mpp_headers INTERFACE)
target_include_directories(rockstream_mpp_headers SYSTEM INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/mpp/include")
target_link_libraries(rockstream_core PRIVATE rockstream_mpp_headers)
endif()
add_executable(rockstream src/main.cpp)
target_link_libraries(rockstream PRIVATE rockstream_core rockstream_options)
set_target_properties(rockstream PROPERTIES CXX_EXTENSIONS OFF)
install(TARGETS rockstream RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
if(BUILD_TESTING)
# Compile only: exercise SDK declarations without requiring device access or
# linking undefined MPP calls. Board builds use their installed SDK instead.
add_library(mpp_headers_check OBJECT tests/mpp_headers_check.cpp)
if(NOT ROCKSTREAM_WITH_MPP)
# Compile the complete native probe against pinned headers on the host.
# Its objects are deliberately never linked into a host executable.
target_sources(mpp_headers_check PRIVATE src/mpp_probe.cpp)
target_include_directories(mpp_headers_check PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
endif()
target_link_libraries(mpp_headers_check PRIVATE rockstream_options)
set_target_properties(mpp_headers_check PROPERTIES CXX_EXTENSIONS OFF)
if(ROCKSTREAM_WITH_MPP)
target_link_libraries(mpp_headers_check PRIVATE RockchipMPP::MPP)
else()
target_link_libraries(mpp_headers_check PRIVATE rockstream_mpp_headers)
endif()
add_test(NAME cli_help COMMAND rockstream --help)
add_test(NAME cli_build_info COMMAND rockstream --build-info)
set_tests_properties(cli_build_info PROPERTIES PASS_REGULAR_EXPRESSION "MPP SDK: (enabled|disabled)")
add_test(NAME cli_reject_unknown COMMAND rockstream --invalid-option)
set_tests_properties(cli_reject_unknown PROPERTIES WILL_FAIL TRUE)
add_test(NAME probe_dry_run COMMAND rockstream encode-probe --dry-run --tiles off --split-ctus 60)
set_tests_properties(probe_dry_run PROPERTIES PASS_REGULAR_EXPRESSION "Dry run: no encoder initialized")
add_executable(probe_tests tests/probe_tests.cpp)
target_link_libraries(probe_tests PRIVATE rockstream_core rockstream_options)
set_target_properties(probe_tests PROPERTIES CXX_EXTENSIONS OFF)
add_test(NAME probe_logic COMMAND probe_tests)
endif()
message(STATUS "rockstream ${PROJECT_VERSION}: ${CMAKE_SYSTEM_PROCESSOR}, MPP=${ROCKSTREAM_WITH_MPP}, sanitizers=${ROCKSTREAM_SANITIZERS}")