Files
dpm-core-ng/CMakeLists.txt

243 lines
9.1 KiB
CMake

cmake_minimum_required(VERSION 3.22)
project(dpm-core VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# ---------------------------------------------------------------------
# libdpm-core.so — the core library (C ABI)
# ---------------------------------------------------------------------
add_library(dpm-core SHARED
src/context.cpp
src/modules.cpp
src/version.cpp
)
target_include_directories(dpm-core PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_compile_definitions(dpm-core PRIVATE
DPM_CORE_VERSION_STR="${PROJECT_VERSION}"
)
# The public C API is the library's entire exported surface; internals
# stay hidden. The version script pins the export list and versions the
# symbols.
target_compile_options(dpm-core PRIVATE
-fvisibility=hidden
-fvisibility-inlines-hidden
)
target_link_options(dpm-core PRIVATE
-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/libdpm-core.map
)
set_property(TARGET dpm-core APPEND PROPERTY
LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/libdpm-core.map
)
target_link_libraries(dpm-core PRIVATE ${CMAKE_DL_LIBS})
set_target_properties(dpm-core PROPERTIES
OUTPUT_NAME "dpm-core"
VERSION ${PROJECT_VERSION}
SOVERSION 1
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
)
# ---------------------------------------------------------------------
# dpm — the CLI (thin client of libdpm-core)
# ---------------------------------------------------------------------
add_executable(dpm src/cli/dpm.cpp)
target_link_libraries(dpm PRIVATE dpm-core)
set_target_properties(dpm PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
BUILD_RPATH "$ORIGIN/../lib"
)
# ---------------------------------------------------------------------
# info — the bundled module (tests and reports core functionality)
# ---------------------------------------------------------------------
add_library(info MODULE
src/bundled-modules/info/info.cpp
src/bundled-modules/info/src/commands.cpp
)
target_include_directories(info PRIVATE src/bundled-modules/info/include)
# The one permitted link dependency: libdpm-core.
target_link_libraries(info PRIVATE dpm-core)
set_target_properties(info PROPERTIES
PREFIX ""
SUFFIX ".so"
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/modules
)
# The module bundles with core, so building the CLI builds it too: after a
# clean, running dpm from the build tree finds a module directory that is
# populated. This orders the build only — the CLI does not link the module.
add_dependencies(dpm info)
# ---------------------------------------------------------------------
# Test fixture modules: one known-good stub, five deliberately broken
# ---------------------------------------------------------------------
enable_testing()
set(FIXTURE_MODULE_DIR ${CMAKE_BINARY_DIR}/tests/fixtures)
foreach(fixture good missing_symbols bad_magic lying_manifest core_too_new bad_version)
add_library(fixture_${fixture} MODULE tests/fixtures/src/${fixture}.cpp)
set_target_properties(fixture_${fixture} PROPERTIES
PREFIX ""
SUFFIX ".so"
OUTPUT_NAME ${fixture}
LIBRARY_OUTPUT_DIRECTORY ${FIXTURE_MODULE_DIR}
)
endforeach()
# ---------------------------------------------------------------------
# Core API test binary — drives libdpm-core through its public C API
# ---------------------------------------------------------------------
add_executable(test_core tests/test_core.cpp)
target_link_libraries(test_core PRIVATE dpm-core)
target_compile_definitions(test_core PRIVATE
TEST_FIXTURE_MODULES="${FIXTURE_MODULE_DIR}"
TEST_FIXTURE_CONF="${CMAKE_CURRENT_SOURCE_DIR}/tests/fixtures/conf"
DPM_CORE_VERSION_EXPECTED="${PROJECT_VERSION}"
)
set_target_properties(test_core PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests
BUILD_RPATH "$ORIGIN/../lib"
)
foreach(fixture good missing_symbols bad_magic lying_manifest core_too_new bad_version)
add_dependencies(test_core fixture_${fixture})
endforeach()
add_test(NAME core_api COMMAND test_core)
# ---------------------------------------------------------------------
# CLI end-to-end tests (the CLI is core's cheapest full-stack client)
# ---------------------------------------------------------------------
add_test(NAME cli_help COMMAND dpm --help)
set_tests_properties(cli_help PROPERTIES PASS_REGULAR_EXPRESSION "Usage: dpm")
add_test(NAME cli_list
COMMAND dpm -c ${CMAKE_CURRENT_SOURCE_DIR}/tests/fixtures/conf
-m ${CMAKE_BINARY_DIR}/modules --list-modules)
set_tests_properties(cli_list PROPERTIES PASS_REGULAR_EXPRESSION "info")
add_test(NAME cli_info_version
COMMAND dpm -c ${CMAKE_CURRENT_SOURCE_DIR}/tests/fixtures/conf
-m ${CMAKE_BINARY_DIR}/modules -L INFO info version)
set_tests_properties(cli_info_version PROPERTIES
PASS_REGULAR_EXPRESSION "libdpm-core Version: ${PROJECT_VERSION}")
add_test(NAME cli_module_not_found
COMMAND dpm -c ${CMAKE_CURRENT_SOURCE_DIR}/tests/fixtures/conf
-m ${CMAKE_BINARY_DIR}/modules nonexistent)
set_tests_properties(cli_module_not_found PROPERTIES WILL_FAIL TRUE)
add_test(NAME cli_rejects_invalid_module
COMMAND dpm -c ${CMAKE_CURRENT_SOURCE_DIR}/tests/fixtures/conf
-m ${FIXTURE_MODULE_DIR} missing_symbols)
set_tests_properties(cli_rejects_invalid_module PROPERTIES WILL_FAIL TRUE)
# ---------------------------------------------------------------------
# Code reference (Doxygen) — optional 'docs' target
# ---------------------------------------------------------------------
option(DPM_DOCS_HTML "Generate the code reference in HTML" OFF)
option(DPM_DOCS_PDF "Generate the code reference as PDF (requires LaTeX)" ON)
find_package(Doxygen)
if(DOXYGEN_FOUND)
set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/docs)
set(DOXYGEN_EXTRACT_ALL YES)
set(DOXYGEN_EXTRACT_STATIC YES)
set(DOXYGEN_QUIET YES)
set(DOXYGEN_WARN_IF_UNDOCUMENTED NO)
set(DOXYGEN_JAVADOC_AUTOBRIEF YES)
if(DPM_DOCS_HTML)
set(DOXYGEN_GENERATE_HTML YES)
else()
set(DOXYGEN_GENERATE_HTML NO)
endif()
if(DPM_DOCS_PDF)
set(DOXYGEN_GENERATE_LATEX YES)
set(DOXYGEN_USE_PDFLATEX YES)
set(DOXYGEN_PDF_HYPERLINKS YES)
else()
set(DOXYGEN_GENERATE_LATEX NO)
endif()
doxygen_add_docs(docs
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src
COMMENT "Generating code reference with Doxygen"
)
if(DPM_DOCS_PDF)
find_program(PDFLATEX_EXECUTABLE pdflatex)
if(PDFLATEX_EXECUTABLE)
add_custom_target(docs-pdf
COMMAND make -C ${CMAKE_BINARY_DIR}/docs/latex
COMMENT "Building PDF code reference"
)
add_dependencies(docs-pdf docs)
else()
message(WARNING "DPM_DOCS_PDF is ON but pdflatex was not found; the docs-pdf target is unavailable")
endif()
endif()
endif()
# ---------------------------------------------------------------------
# Clean
# ---------------------------------------------------------------------
# clean empties the build directory: every artifact, every generated tree,
# and the generated build system itself, so that building again requires
# regenerating the directory first.
#
# Order is load-bearing. This list becomes one script run by cmake -P: it is
# parsed whole before it executes, but a removal that fails aborts the rest,
# so anything named after that point survives. Leaves that nothing depends
# on come first, and the entries most likely to be held by an outside
# process — the IDE's file-API directory — come last, where a failure
# costs nothing. The build system make is running from is named late for
# the same reason, since by then the script is already in memory.
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES
${CMAKE_BINARY_DIR}/Testing
${CMAKE_BINARY_DIR}/bin
${CMAKE_BINARY_DIR}/lib
${CMAKE_BINARY_DIR}/modules
${CMAKE_BINARY_DIR}/tests
${CMAKE_BINARY_DIR}/docs
${CMAKE_BINARY_DIR}/CMakeDoxyfile.in
${CMAKE_BINARY_DIR}/CMakeDoxyfile.tpl
${CMAKE_BINARY_DIR}/CMakeDoxygenDefaults.cmake
${CMAKE_BINARY_DIR}/Doxyfile.docs
${CMAKE_BINARY_DIR}/compile_commands.json
${CMAKE_BINARY_DIR}/cmake_install.cmake
${CMAKE_BINARY_DIR}/CTestTestfile.cmake
${CMAKE_BINARY_DIR}/CMakeCache.txt
${CMAKE_BINARY_DIR}/Makefile
${CMAKE_BINARY_DIR}/CMakeFiles
${CMAKE_BINARY_DIR}/.cmake
)
# ---------------------------------------------------------------------
# Installation
# ---------------------------------------------------------------------
install(TARGETS dpm RUNTIME DESTINATION bin)
install(TARGETS dpm-core LIBRARY DESTINATION lib)
install(TARGETS info LIBRARY DESTINATION lib/dpm/modules)
install(DIRECTORY include/dpm DESTINATION include)
install(FILES data/core.conf DESTINATION /etc/dpm/conf.d)