Files
dpm-core-ng/CMakeLists.txt
Christopher M. Punches 282423d768 Read the version from version.cpp instead of declaring it twice
The library's version reached the build through project(), and reached
the library itself through a separate literal in version.cpp. The two
had to be kept equal by hand; the tests caught drift but the number was
written in both places.

CMakeLists.txt now reads DPM_CORE_VERSION_STR out of the source and
passes it to project(), so the soname, the artifact filenames, the
generated PDF's name, and the value the library reports all derive from
one line. Configuration fails outright if that declaration is missing.

SOVERSION follows PROJECT_VERSION_MAJOR rather than a hardcoded 1.
2026-08-16 01:06:44 -04:00

162 lines
6.2 KiB
CMake

cmake_minimum_required(VERSION 3.22)
# libdpm-core.so's version is declared in src/core/version.cpp, the file
# that reports it. The build reads that declaration rather than carrying
# its own copy, so the soname, the artifact filenames, and the version
# the library answers with all derive from one line of source.
file(READ src/core/version.cpp DPM_VERSION_SOURCE)
string(REGEX MATCH "DPM_CORE_VERSION_STR[ \t]+\"([0-9]+\\.[0-9]+\\.[0-9]+)\""
DPM_VERSION_MATCH "${DPM_VERSION_SOURCE}")
if(NOT CMAKE_MATCH_1)
message(FATAL_ERROR
"No DPM_CORE_VERSION_STR found in src/core/version.cpp")
endif()
project(dpm-core VERSION ${CMAKE_MATCH_1} LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# ---------------------------------------------------------------------
# libdpm-core.so — the library (C ABI)
# ---------------------------------------------------------------------
add_library(dpm-core SHARED
src/core/context.cpp
src/core/modules.cpp
src/core/version.cpp
)
target_include_directories(dpm-core PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# 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/core/libdpm-core.map
)
set_property(TARGET dpm-core APPEND PROPERTY
LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/core/libdpm-core.map
)
target_link_libraries(dpm-core PRIVATE ${CMAKE_DL_LIBS})
set_target_properties(dpm-core PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
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 libdpm-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 libdpm-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)
# ---------------------------------------------------------------------
# Tests
#
# The test targets and cases are defined in tests/CMakeLists.txt. The
# paths they build into are named here, above that directory, so each is
# written once and the clean rule below refers to the same values.
# ---------------------------------------------------------------------
enable_testing()
set(DPM_TEST_DIR ${CMAKE_BINARY_DIR}/tests)
set(DPM_TEST_FIXTURE_DIR ${DPM_TEST_DIR}/fixtures)
set(DPM_TEST_RESULTS_DIR ${CMAKE_BINARY_DIR}/test-results)
# CTest's scratch area is named by its BuildDirectory configuration option.
# Writing it into DartConfiguration.tcl puts it where ctest reads it on every
# invocation — the test target, a bare ctest, and the IDE's test discovery
# alike — rather than only the ones the build drives.
file(WRITE ${CMAKE_BINARY_DIR}/DartConfiguration.tcl
"BuildDirectory: ${DPM_TEST_RESULTS_DIR}\n")
add_subdirectory(tests)
# ---------------------------------------------------------------------
# Documentation
#
# The Doxygen configuration and the 'docs' target are defined in
# docs/CMakeLists.txt. The paths it builds into are named here, above
# that directory, so each is written once and the clean rule below
# refers to the same values.
#
# The subdirectory is given its own binary directory so that CMake's
# scaffolding stays out of the documentation output.
# ---------------------------------------------------------------------
set(DPM_DOCS_DIR ${CMAKE_BINARY_DIR}/docs)
set(DPM_DOCS_TMP_DIR ${DPM_DOCS_DIR}/tmp)
set(DPM_DOCS_PDF_DIR ${DPM_DOCS_DIR}/pdf)
set(DPM_DOCS_HTML_DIR ${DPM_DOCS_DIR}/html)
add_subdirectory(docs ${CMAKE_BINARY_DIR}/docs-build)
# ---------------------------------------------------------------------
# Clean
# ---------------------------------------------------------------------
# clean removes what the build produced: the artifact directories, the
# generated documentation, and the test scratch areas.
#
# The generated build system stays. CMakeCache.txt, the makefiles,
# CMakeFiles/, and the CMake file API directory under .cmake/ are what an
# IDE reads to know the project's targets exist; deleting them leaves the
# directory unconfigured, so every target in the IDE stops resolving until
# the project is reloaded. Removing the build system is what configuring a
# fresh directory is for.
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES
${DPM_TEST_RESULTS_DIR}
${CMAKE_BINARY_DIR}/Testing
${CMAKE_BINARY_DIR}/bin
${CMAKE_BINARY_DIR}/lib
${CMAKE_BINARY_DIR}/modules
${DPM_TEST_DIR}
${DPM_DOCS_DIR}
)
# ---------------------------------------------------------------------
# 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)