Skip to content
Open
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
79 changes: 79 additions & 0 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
name: CMake

on:
push:
branches: ["develop"]
pull_request:
branches: ["develop"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
schedule:
# run at 15:30 on day-of-month 7.
- cron: '30 15 7 * *'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: release
CTEST_OUTPUT_ON_FAILURE: 1

jobs:
build:
strategy:
fail-fast: false

matrix:
os: [windows]
include:
- { os: macos, uname: appleclang }
# XXX - { os: ubuntu, uname: gcc }
- { os: ubuntu, uname: llvm }
- { os: windows, uname: msvc }

# TODO(CK):
# type: [shared, static]
# include:
# - { type: shared, shared: YES }
# - { type: static, shared: NO }

runs-on: ${{ matrix.os }}-latest

steps:
- uses: actions/checkout@v4
- name: Setup build environment
uses: lukka/get-cmake@latest
with:
cmakeVersion: "~4.2.1"
ninjaVersion: "^1.13.0"

- name: Setup MSVC
if: startsWith(matrix.os, 'windows')
uses: TheMrMilchmann/setup-msvc-dev@v3
with:
arch: x64

- name: Setup Cpp
if: matrix.os != 'windows'
uses: aminya/setup-cpp@v1
with:
# XXX compiler: ${{matrix.uname}}
compiler: llvm

- name: Configure CMake
run: cmake --preset ${{matrix.uname}}-${{env.BUILD_TYPE}} --log-level=VERBOSE # XXX -Wdev

- name: Build
# Build your program with the given configuration
run: cmake --build --preset ${{matrix.uname}}-${{env.BUILD_TYPE}}

- name: Test
# Execute tests defined by the CMake configuration
run: ctest --preset ${{matrix.uname}}-${{env.BUILD_TYPE}}

# - name: Install
# # Install the project artefacts to CMAKE_INSTALL_PREFIX
# run: cmake --build --preset ${{matrix.uname}}-${{env.BUILD_TYPE}} --target install
68 changes: 46 additions & 22 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ project(

# gersemi: off

# Modules opt in only on compilers that support g++-15 and clang-20+
# Modules opt in only on compilers that support it: msvc, g++-15 and clang-20+
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 20)
set(CMAKE_CXX_SCAN_FOR_MODULES 1)
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 15)
set(CMAKE_CXX_SCAN_FOR_MODULES 1)
elseif(MSVC)
set(CMAKE_CXX_SCAN_FOR_MODULES 1)
else()
set(CMAKE_CXX_SCAN_FOR_MODULES 0)
endif()

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE)

# [CMAKE.SKIP_TESTS]
option(
Expand All @@ -43,61 +47,80 @@ option(
)

message(
"Compiler is: ${CMAKE_CXX_COMPILER_ID} version: ${CMAKE_CXX_COMPILER_VERSION}"
"Compiler is: ${CMAKE_CXX_COMPILER_ID} version: ${CMAKE_CXX_COMPILER_VERSION}"
)
message(
"cmake is: ${CMAKE_VERSION} modules scan : ${CMAKE_CXX_SCAN_FOR_MODULES}"
"cmake is: ${CMAKE_VERSION} modules scan: ${CMAKE_CXX_SCAN_FOR_MODULES}"
)

# gersemi: on

if(CMAKE_CXX_SCAN_FOR_MODULES)
add_library(beman.scope)

include(GenerateExportHeader)

generate_export_header(
beman.scope
BASE_NAME beman.scope
EXPORT_FILE_NAME beman/scope/modules_export.hpp
)
else()
add_library(beman.scope INTERFACE)
endif()

if(CMAKE_CXX_SCAN_FOR_MODULES)
target_sources(
beman.scope
PUBLIC
FILE_SET HEADERS
BASE_DIRS include
FILES include/beman/scope/scope.hpp
BASE_DIRS include ${CMAKE_CURRENT_BINARY_DIR}
FILES
include/beman/scope/scope.hpp
include/beman/scope/scope_impl.hpp
${CMAKE_CURRENT_BINARY_DIR}/beman/scope/modules_export.hpp
PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS include
FILES include/beman/scope/beman.scope.cppm
BASE_DIRS include
FILES include/beman/scope/beman.scope.cppm
)
target_compile_features(beman.scope PUBLIC cxx_std_20)
else()
add_library(beman.scope INTERFACE)
target_sources(
beman.scope
INTERFACE
FILE_SET HEADERS
BASE_DIRS include
FILES include/beman/scope/scope.hpp
BASE_DIRS include ${CMAKE_CURRENT_BINARY_DIR}
FILES
include/beman/scope/scope.hpp
include/beman/scope/scope_impl.hpp
# NO! ${CMAKE_CURRENT_BINARY_DIR}/beman/scope/modules_export.hpp
)
endif()

add_library(beman::scope ALIAS beman.scope)

set_target_properties(
beman.scope
PROPERTIES
VERIFY_INTERFACE_HEADER_SETS ON
EXPORT_NAME scope
PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON EXPORT_NAME scope
)

include(GNUInstallDirs)

set(package_install_dir ${CMAKE_INSTALL_LIBDIR}/cmake/beman.scope)

# TBD: always? CK
install(
TARGETS beman.scope
COMPONENT beman.scope
EXPORT beman.scope-targets

FILE_SET CXX_MODULES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILE_SET CXX_MODULES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
CXX_MODULES_BMI
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/beman.scope/bmi-${CMAKE_CXX_COMPILER_ID}_$<CONFIG>
DESTINATION
${package_install_dir}/bmi-${CMAKE_CXX_COMPILER_ID}_$<CONFIG>
FILE_SET HEADERS
)

# gersemi: on

if(BEMAN_SCOPE_INSTALL_CONFIG_FILE_PACKAGE)
include(CMakePackageConfigHelpers)

Expand All @@ -110,22 +133,23 @@ if(BEMAN_SCOPE_INSTALL_CONFIG_FILE_PACKAGE)
FILES
cmake/beman.scope-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/beman.scope-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/beman.scope
DESTINATION ${package_install_dir}
COMPONENT beman.scope
)

install(
EXPORT beman.scope-targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/beman.scope
DESTINATION ${package_install_dir}
NAMESPACE beman::
CXX_MODULES_DIRECTORY
cxx-modules
COMPONENT beman.scope
)
endif()

enable_testing()

if(BEMAN_SCOPE_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()

Expand Down
12 changes: 8 additions & 4 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_CXX_STANDARD": "20",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "./infra/cmake/use-fetch-content.cmake"
"CMAKE_CXX_EXTENSIONS": true,
"CMAKE_CXX_STANDARD": "23",
"CMAKE_CXX_STANDARD_REQUIRED": true,
"CMAKE_EXPORT_COMPILE_COMMANDS": true,
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "infra/cmake/use-fetch-content.cmake"
}
},
{
Expand Down Expand Up @@ -68,7 +70,7 @@
"_release-base"
],
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "infra/cmake/llvm-toolchain.cmake"
"CMAKE_TOOLCHAIN_FILE": "infra/cmake/llvm-libc++-toolchain.cmake"
}
},
{
Expand Down Expand Up @@ -101,6 +103,7 @@
"_debug-base"
],
"cacheVariables": {
"BUILD_SHARED_LIBS": false,
"CMAKE_TOOLCHAIN_FILE": "infra/cmake/msvc-toolchain.cmake"
}
},
Expand All @@ -112,6 +115,7 @@
"_release-base"
],
"cacheVariables": {
"BUILD_SHARED_LIBS": false,
"CMAKE_TOOLCHAIN_FILE": "infra/cmake/msvc-toolchain.cmake"
}
}
Expand Down
21 changes: 20 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

cmake_minimum_required(VERSION 3.28...4.2)

project(beman.scope.example LANGUAGES CXX)

if(PROJECT_IS_TOP_LEVEL)
if(NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_EXTENSIONS YES)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
endif()
set(CMAKE_CXX_SCAN_FOR_MODULES OFF)

find_package(beman.scope REQUIRED)

enable_testing()
endif()

set(ALL_EXAMPLES scope_example unique_resource unique_resource-file)

# module tests will only compile with gcc15 or clang20 and above
if(CMAKE_CXX_SCAN_FOR_MODULES AND CMAKE_CXX_MODULE_STD)
# NOTE: needs C++23 or newer! CK
if(CMAKE_CXX_SCAN_FOR_MODULES)
list(APPEND ALL_EXAMPLES scope-module)
endif()

Expand All @@ -13,4 +31,5 @@ foreach(example ${ALL_EXAMPLES})
add_executable(${example})
target_sources(${example} PRIVATE ${example}.cpp)
target_link_libraries(${example} PRIVATE beman::scope)
add_test(NAME ${example} COMMAND ${example})
endforeach()
54 changes: 35 additions & 19 deletions examples/scope-module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,50 @@
// destroy noisy
// scope exit: true success: true fail: false

// #ifdef HAS_MODULE_STD
#include <cassert>

// NOTE: this needs C++23! CK
#ifdef HAS_MODULE_STD
import std;
// #else
// NOTE: this needs C++23!
// #include <print>
// #endif
#endif

// for g++-15 the order is important -- import after #includes
import beman.scope;

// clang-format off
struct noisy_resource {
noisy_resource() { std::print( "construct noisy\n" ); }
~noisy_resource() { std::print( "destroy noisy\n" ); }
namespace {

struct DummyResource {
bool& cleaned;

DummyResource(bool& flag) : cleaned(flag) { cleaned = false; }

[[nodiscard]] bool is_clean() const { return cleaned; }
};

} // namespace

int main() {

bool exit_ran, success_ran, fail_ran = false;
bool exit_ran{};
bool success_ran{};
bool fail_ran{};
bool cleaned{true};
{
std::print("--> scope start\n");
beman::scope::scope_exit _([&exit_ran] { exit_ran = true; });
beman::scope::scope_success _([&success_ran] { success_ran = true; });
beman::scope::scope_fail _([&fail_ran] { fail_ran = true; });
auto resource_ptr = beman::scope::unique_resource(new noisy_resource(),
// Cleanup function
[](noisy_resource* ptr) { delete ptr; });
std::print("--> scope end\n");
// clang-format off
beman::scope::scope_exit _se([&exit_ran] { exit_ran = true; });
beman::scope::scope_success _ss([&success_ran] { success_ran = true; });
beman::scope::scope_fail _sf([&fail_ran] { fail_ran = true; });
auto resource_ptr = beman::scope::unique_resource(new DummyResource(cleaned),
[](DummyResource* ptr) { ptr->cleaned = true; delete ptr; });
// clang-format on

assert(cleaned == false);
assert(resource_ptr->is_clean() == false);
} // Normal scope exit

std::print("scope exit: {} success: {} fail: {} \n", exit_ran, success_ran, fail_ran);
assert(exit_ran == true);
assert(success_ran == true);
assert(fail_ran == false);
assert(cleaned == true);
}
// clang-format on
21 changes: 21 additions & 0 deletions gcovr.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
root = .
search-path = build

filter = examples/*
# filter = src/*
filter = include/*

exclude-directories = stagedir
exclude-directories = build/*/*/_deps
exclude-directories = tests
exclude-directories = conan

gcov-ignore-parse-errors = all
print-summary = yes

html-details = build/coverage/index.html

cobertura-pretty = yes
cobertura = build/cobertura.xml

#TBD delete-gcov-files = yes
Loading