Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 35 additions & 33 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,23 @@

cmake_minimum_required(VERSION 3.30...4.2)

include(cmake/prelude.cmake)
include(./cmake/prelude.cmake)

#===================================================
project(beman_execution VERSION 0.1.0 LANGUAGES CXX)
#===================================================

# Modules opt in only on compilers that support it: msvc, g++-15 and clang-20+
include(cxx-modules-rules)
include(./cmake/cxx-modules-rules.cmake)

set(TARGET_NAME beman_execution_headers) # used in src, and docs
set(TARGET_NAMESPACE beman) # NOTE: only still used in docs?
set(TARGET_PREFIX ${PROJECT_NAME}) # NOTE: only still used in docs?
set(TARGET_PACKAGE_NAME ${PROJECT_NAME}-config)
set(TARGETS_EXPORT_NAME ${PROJECT_NAME}-config-targets)

# XXX set(TARGET_PACKAGE_NAME ${PROJECT_NAME}-config)
# XXX set(TARGETS_EXPORT_NAME ${PROJECT_NAME}-config-targets)

set(TARGETS_EXPORT_NAME ${PROJECT_NAME}-targets)

#===============================================================================
if(BEMAN_USE_MODULES)
Expand All @@ -28,7 +31,7 @@ if(BEMAN_USE_MODULES)
# CMake requires the language standard to be specified as compile feature
# when a target provides C++23 modules and the target will be installed
add_library(beman_execution STATIC)
add_library(beman::beman_execution ALIAS beman_execution)
add_library(beman::execution ALIAS beman_execution)
target_compile_features(
beman_execution
PUBLIC cxx_std_${CMAKE_CXX_STANDARD}
Expand Down Expand Up @@ -72,13 +75,13 @@ option(
)

option(
BEMAN_EXECUTION_ENABLE_INSTALL
BEMAN_EXECUTION_INSTALL_CONFIG_FILE_PACKAGE
"Install the project components. Values: { ON, OFF }."
${PROJECT_IS_TOP_LEVEL}
)

include(GNUInstallDirs)
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
# include(GNUInstallDirs)
# set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})

add_subdirectory(src/beman/execution)

Expand All @@ -93,34 +96,33 @@ if(BEMAN_EXECUTION_BUILD_EXAMPLES)
add_subdirectory(docs/code)
endif()

if(NOT BEMAN_EXECUTION_ENABLE_INSTALL OR CMAKE_SKIP_INSTALL_RULES)
if(NOT BEMAN_EXECUTION_INSTALL_CONFIG_FILE_PACKAGE OR CMAKE_SKIP_INSTALL_RULES)
return()
endif()

include(infra/cmake/beman-install-library-config.cmake)
# FIXME: install TARGETS target beman.execution is exported but not all of its interface file sets are installed
# TODO: beman_install_library(beman_execution beman_execution_headers)

include(CMakePackageConfigHelpers)

write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}-version.cmake
VERSION ${CMAKE_PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)

configure_package_config_file(
"cmake/Config.cmake.in"
${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}.cmake
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)

install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}.cmake
${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}-version.cmake
DESTINATION ${INSTALL_CONFIGDIR}
)
include(./cmake/beman-install-library-config.cmake)
beman_install_library(beman_execution headers)

# include(CMakePackageConfigHelpers)
#
# write_basic_package_version_file(
# ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}-version.cmake
# VERSION ${CMAKE_PROJECT_VERSION}
# COMPATIBILITY AnyNewerVersion
# )
#
# configure_package_config_file(
# "cmake/Config.cmake.in"
# ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}.cmake
# INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
# )
#
# install(
# FILES
# ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}.cmake
# ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PACKAGE_NAME}-version.cmake
# DESTINATION ${INSTALL_CONFIGDIR}
# )

set(CPACK_GENERATOR TGZ)
include(CPack)
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ endif
# TODO: beman.execution.examples.modules
# FIXME: beman.execution.execution-module.test beman.execution.stop-token-module.test

default: test
default: release

all: $(SANITIZERS)

Expand All @@ -113,14 +113,18 @@ doc:
# $(SANITIZERS):
# $(MAKE) SANITIZER=$@

# ==========================================================
# NOTE: cmake configure to only test without modules! CK
# ==========================================================
build:
cmake -G Ninja -S $(SOURCEDIR) -B $(BUILD) $(TOOLCHAIN) $(SYSROOT) \
-D CMAKE_EXPORT_COMPILE_COMMANDS=ON \
-D CMAKE_SKIP_INSTALL_RULES=OFF \
-D CMAKE_CXX_STANDARD=23 \
-D CMAKE_CXX_EXTENSIONS=ON \
-D CMAKE_CXX_STANDARD_REQUIRED=ON \
-D CMAKE_CXX_SCAN_FOR_MODULES=ON \
-D CMAKE_CXX_SCAN_FOR_MODULES=OFF \
-D BEMAN_USE_MODULES=OFF \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_CXX_COMPILER=$(CXX)
cmake --build $(BUILD)
Expand All @@ -136,11 +140,13 @@ install: test
CMakeUserPresets.json:: cmake/CMakeUserPresets.json
ln -s $< $@

# ==========================================================
release: CMakeUserPresets.json
cmake --preset $@ --log-level=TRACE # XXX --fresh
ln -fs $(BUILDROOT)/$@/compile_commands.json .
cmake --workflow --preset $@

# ==========================================================
debug: CMakeUserPresets.json
cmake --preset $@ --log-level=TRACE # XXX --fresh
ln -fs $(BUILDROOT)build/$@/compile_commands.json .
Expand Down Expand Up @@ -170,9 +176,11 @@ clang-tidy: $(BUILD)/compile_commands.json
codespell:
pre-commit run $@

# ==========================================================
format:
pre-commit autoupdate
pre-commit run --all
# ==========================================================

cmake-format:
pre-commit run gersemi
Expand Down
202 changes: 202 additions & 0 deletions cmake/beman-install-library-config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
include_guard(GLOBAL)

# This file defines the function `beman_install_library` which is used to
# install a library target and its headers, along with optional CMake
# configuration files.
#
# The function is designed to be reusable across different Beman libraries.

function(beman_install_library name interface)
# Usage
# -----
#
# beman_install_library(NAME INTERFACE)
#
# Brief
# -----
#
# This function installs the specified library target and its headers.
# It also handles the installation of the CMake configuration files if needed.
#
# CMake variables
# ---------------
#
# Note that configuration of the installation is generally controlled by CMake
# cache variables so that they can be controlled by the user or tool running the
# `cmake` command. Neither `CMakeLists.txt` nor `*.cmake` files should set these
# variables directly.
#
# - BEMAN_INSTALL_CONFIG_FILE_PACKAGES:
# List of packages that require config file installation.
# If the package name is in this list, it will install the config file.
#
# - <PREFIX>_INSTALL_CONFIG_FILE_PACKAGE:
# Boolean to control config file installation for the specific library.
# The prefix `<PREFIX>` is the uppercased name of the library with dots
# replaced by underscores.
#
# if(NOT TARGET "${name}")
# message(FATAL_ERROR "Target '${name}' does not exist.")
# endif()

# if(NOT ARGN STREQUAL "")
# message(
# FATAL_ERROR
# "beman_install_library does not accept extra arguments: ${ARGN}"
# )
# endif()

# XXX Given foo.bar, the component name is bar
# string(REPLACE "." ";" name_parts "${name}")
# XXX fail if the name doesn't look like foo.bar
# list(LENGTH name_parts name_parts_length)
# if(NOT name_parts_length EQUAL 2)
# message(
# FATAL_ERROR
# "beman_install_library expects a name of the form 'beman.<name>', got '${name}'"
# )
# endif()

string(REPLACE "beman_" "" name_parts "${name}")
set(component_name ${name_parts})

set(target_name "${name}")

# COMPONENT <component>
# Specify an installation component name with which the install rule is associated,
# such as Runtime or Development.
set(install_component_name "${name}") # TODO(CK): this is not common name!

set(export_name "${name}")
set(package_name "${name}")
# XXX list(GET name_parts -1 component_name)

set(target_list)
if(TARGET "${target_name}")
set_target_properties(
"${target_name}"
PROPERTIES EXPORT_NAME "${component_name}"
)
message(
VERBOSE
"beman-install-library: COMPONENT ${component_name} for TARGET '${target_name}'"
)
list(APPEND target_list "${target_name}")
endif()

if(interface AND TARGET "${target_name}_${interface}")
set_target_properties(
"${target_name}_${interface}"
PROPERTIES EXPORT_NAME "${component_name}_${interface}"
)
message(
VERBOSE
"beman-install-library: COMPONENT ${component_name}_${interface} for TARGET '${name}_${interface}'"
)
list(APPEND target_list "${target_name}_${interface}")
endif()
Comment on lines +89 to +98
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ednolan my quick and dirty hack to install the module library and the interface library


include(GNUInstallDirs)

install(
TARGETS ${target_list}
COMPONENT "${install_component_name}"
EXPORT "${export_name}"
FILE_SET HEADERS
FILE_SET CXX_MODULES
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${package_name}/modules
)

# Determine the prefix for project-specific variables
string(TOUPPER "${name}" project_prefix)
# XXX string(REPLACE "." "_" project_prefix "${project_prefix}")

option(
${project_prefix}_INSTALL_CONFIG_FILE_PACKAGE
"Enable creating and installing a CMake config-file package. Default: ON. Values: { ON, OFF }."
ON
)

# By default, install the config package
set(install_config_package ON)

# Turn OFF installation of config package by default if,
# in order of precedence:
# 1. The specific package variable is set to OFF
# 2. The package name is not in the list of packages to install config files
if(DEFINED BEMAN_INSTALL_CONFIG_FILE_PACKAGES)
if(
NOT "${install_component_name}"
IN_LIST
BEMAN_INSTALL_CONFIG_FILE_PACKAGES
)
set(install_config_package OFF)
endif()
endif()
if(DEFINED ${project_prefix}_INSTALL_CONFIG_FILE_PACKAGE)
set(install_config_package
${${project_prefix}_INSTALL_CONFIG_FILE_PACKAGE}
)
endif()

if(install_config_package)
message(
VERBOSE
"beman-install-library: Installing a config package for '${name}'"
)

include(CMakePackageConfigHelpers)

find_file(
config_file_template
NAMES "${package_name}-config.cmake.in"
PATHS "${PROJECT_SOURCE_DIR}/cmake"
NO_DEFAULT_PATH
NO_CACHE
REQUIRED
)
set(config_package_file
"${CMAKE_CURRENT_BINARY_DIR}/${package_name}-config.cmake"
)
set(package_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${package_name}")
configure_package_config_file(
"${config_file_template}"
"${config_package_file}"
INSTALL_DESTINATION "${package_install_dir}"
PATH_VARS PROJECT_NAME PROJECT_VERSION
)

set(config_version_file
"${CMAKE_CURRENT_BINARY_DIR}/${package_name}-config-version.cmake"
)
write_basic_package_version_file(
"${config_version_file}"
VERSION "${PROJECT_VERSION}"
COMPATIBILITY ExactVersion
)

install(
FILES "${config_package_file}" "${config_version_file}"
DESTINATION "${package_install_dir}"
COMPONENT "${install_component_name}"
)

# NOTE: must be same value as ${TARGETS_EXPORT_NAME}.cmake! CK
set(config_targets_file "${package_name}-targets.cmake")
install(
EXPORT "${export_name}"
DESTINATION "${package_install_dir}"
NAMESPACE beman::
FILE "${config_targets_file}"
CXX_MODULES_DIRECTORY
cxx-modules
COMPONENT "${install_component_name}"
)
else()
message(
WARNING
"beman-install-library: Not installing a config package for '${name}'"
)
endif()
endfunction()
7 changes: 7 additions & 0 deletions cmake/beman_execution-config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# cmake/Config.cmake.in -*-makefile-*-
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
check_required_components("@TARGET_LIBRARY@")
Loading