The fixture targets, the test binary, and the six test cases live beside the sources they build, leaving the top-level file with enable_testing, the ctest scratch-area write, and the add_subdirectory call. The paths both files need are set once above that call, so the child's output directories and the parent's clean rule refer to the same variables rather than repeating the paths.
228 lines
8.8 KiB
CMake
228 lines
8.8 KiB
CMake
cmake_minimum_required(VERSION 3.22)
|
|
project(dpm-core VERSION 1.0.0 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
|
|
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 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)
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Code reference (Doxygen) — optional 'docs' target
|
|
# ---------------------------------------------------------------------
|
|
option(DPM_DOCS_HTML "Generate the code reference in HTML" ON)
|
|
option(DPM_DOCS_PDF "Generate the code reference as PDF (requires LaTeX)" ON)
|
|
|
|
find_package(Doxygen)
|
|
if(DOXYGEN_FOUND)
|
|
# Doxygen and LaTeX both work in scratch space under docs/tmp. The
|
|
# finished document is copied up into docs/, so the directory a user
|
|
# opens holds documentation and nothing else.
|
|
set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/docs/tmp)
|
|
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()
|
|
|
|
# The prose documents, each rendered as its own page in the generated
|
|
# reference. Named one per line so the set of documents reaching the
|
|
# output is stated here instead of implied by a directory.
|
|
set(DPM_DOC_PAGES
|
|
${CMAKE_CURRENT_SOURCE_DIR}/docs/OVERVIEW.md
|
|
${CMAKE_CURRENT_SOURCE_DIR}/docs/DESIGN.md
|
|
${CMAKE_CURRENT_SOURCE_DIR}/docs/CONSUMERS.md
|
|
${CMAKE_CURRENT_SOURCE_DIR}/docs/MODULES.md
|
|
${CMAKE_CURRENT_SOURCE_DIR}/docs/BUILD.md
|
|
${CMAKE_CURRENT_SOURCE_DIR}/docs/DOCUMENTATION.md
|
|
)
|
|
|
|
# Two kinds of input: include/ and src/ supply the API and internals
|
|
# reference extracted from the source, DPM_DOC_PAGES supplies the
|
|
# prose pages.
|
|
#
|
|
# One target, so `cmake --build <dir> --target docs` is the whole
|
|
# procedure and the IDE lists a single entry for it. The commands
|
|
# below run after Doxygen and place the finished documents.
|
|
doxygen_add_docs(docs
|
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
|
${DPM_DOC_PAGES}
|
|
COMMENT "Generating the reference with Doxygen"
|
|
)
|
|
|
|
if(DPM_DOCS_PDF)
|
|
find_program(PDFLATEX_EXECUTABLE pdflatex)
|
|
if(PDFLATEX_EXECUTABLE)
|
|
add_custom_command(TARGET docs POST_BUILD
|
|
COMMAND make -C ${CMAKE_BINARY_DIR}/docs/tmp/latex
|
|
COMMAND ${CMAKE_COMMAND} -E rm -rf
|
|
${CMAKE_BINARY_DIR}/docs/pdf
|
|
COMMAND ${CMAKE_COMMAND} -E copy
|
|
${CMAKE_BINARY_DIR}/docs/tmp/latex/refman.pdf
|
|
${CMAKE_BINARY_DIR}/docs/pdf/dpm-core-${PROJECT_VERSION}.pdf
|
|
COMMENT "Compiling the PDF reference"
|
|
)
|
|
else()
|
|
message(WARNING "DPM_DOCS_PDF is ON but pdflatex was not found; no PDF will be produced")
|
|
endif()
|
|
endif()
|
|
|
|
if(DPM_DOCS_HTML)
|
|
add_custom_command(TARGET docs POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E rm -rf
|
|
${CMAKE_BINARY_DIR}/docs/html
|
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
|
${CMAKE_BINARY_DIR}/docs/tmp/html
|
|
${CMAKE_BINARY_DIR}/docs/html
|
|
COMMENT "Placing the HTML reference"
|
|
)
|
|
endif()
|
|
|
|
# Doxygen keeps output files it judges unchanged, so a run over a
|
|
# populated scratch directory can carry pages forward from an earlier
|
|
# one. Removing it here means the next run regenerates everything,
|
|
# and leaves docs/ holding the finished documents alone.
|
|
add_custom_command(TARGET docs POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E rm -rf ${CMAKE_BINARY_DIR}/docs/tmp
|
|
COMMENT "Clearing the generators' scratch directory"
|
|
)
|
|
endif()
|
|
|
|
# ---------------------------------------------------------------------
|
|
# 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}
|
|
${CMAKE_BINARY_DIR}/docs
|
|
)
|
|
|
|
# ---------------------------------------------------------------------
|
|
# 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)
|