diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index e005487..71eb660 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -27,8 +27,8 @@ jobs: - name: Setup build environment uses: lukka/get-cmake@latest with: - cmakeVersion: "~3.28.0" - ninjaVersion: "^1.11.1" + cmakeVersion: latest + ninjaVersion: latest - name: Setup MSVC if: startsWith(matrix.presets.platform, 'windows') uses: TheMrMilchmann/setup-msvc-dev@v3 @@ -80,8 +80,8 @@ jobs: - name: Install Ninja uses: lukka/get-cmake@latest with: - cmakeVersion: "~4.0.0" - ninjaVersion: "^1.11.1" + cmakeVersion: latest + ninjaVersion: latest - name: Setup MSVC if: startsWith(matrix.platform.os, 'windows') uses: TheMrMilchmann/setup-msvc-dev@v3 @@ -139,8 +139,8 @@ jobs: - name: Setup build environment uses: lukka/get-cmake@latest with: - cmakeVersion: "~3.28.0" - ninjaVersion: "^1.11.1" + cmakeVersion: latest + ninjaVersion: latest - name: Print installed softwares run: | cmake --version @@ -183,8 +183,8 @@ jobs: - name: Setup build environment uses: lukka/get-cmake@latest with: - cmakeVersion: "~4.0.0" - ninjaVersion: "^1.11.1" + cmakeVersion: latest + ninjaVersion: latest - name: Install Compiler id: install-compiler run: | diff --git a/.gitignore b/.gitignore index 6c1ce4b..4fb9ec4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # ignore temp build files /compile_commands.json /build +**/_deps/ +**/CMakeFiles/ # ignore emacs temp files *~ diff --git a/CMakeLists.txt b/CMakeLists.txt index afdaf7d..ac350eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,23 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -cmake_minimum_required(VERSION 3.28) +if(CMAKE_CXX_STANDARD GREATER_EQUAL 23) + if(CMAKE_CXX_MODULE_STD) + if(CMAKE_VERSION VERSION_EQUAL 4.0.2) + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "a9e1cf81-9932-4810-974b-6eccaf14e457" + ) + else() + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) + endif() + set(CMAKE_CXX_SCAN_FOR_MODULES 1) + add_definitions(-DHAS_STDLIB_MODULES) + endif() + set(CMAKE_CXX_STANDARD_REQUIRED OFF) +endif() + +cmake_minimum_required(VERSION 4.0) project( beman.scope @@ -12,15 +29,45 @@ project( # gersemi: off # Modules opt in only on compilers that support 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() +if(CMAKE_CXX_STANDARD GREATER_EQUAL 23) + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 20) + if(APPLE AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 20.1.5) + execute_process(OUTPUT_VARIABLE LLVM_PREFIX COMMAND brew --prefix llvm@20 COMMAND_ECHO STDOUT) + string(STRIP ${LLVM_PREFIX} LLVM_PREFIX) + file(REAL_PATH ${LLVM_PREFIX} LLVM_ROOT) + set(LLVM_ROOT ${LLVM_ROOT} CACHE PATH "") + message(STATUS "LLVM_ROOT=${LLVM_ROOT}") + + add_compile_options(-fexperimental-library) + add_link_options(-L${LLVM_ROOT}/lib/c++ -lc++experimental) + add_compile_options(-stdlib=libc++) + add_link_options(-stdlib=libc++) + endif() + 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) + endif() +else() set(CMAKE_CXX_SCAN_FOR_MODULES 0) endif() -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +if(CMAKE_CXX_SCAN_FOR_MODULES) + set(CMAKE_CXX_STANDARD_REQUIRED OFF) +endif() + +set(CMAKE_EXPORT_COMPILE_COMMANDS OFF) +if(CMAKE_EXPORT_COMPILE_COMMANDS) + set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) + find_program(CLANG_TIDY_EXE NAMES clang-tidy clang-tidy-20 DOC "Path to clang-tidy executable") +endif() + +include(CMakePrintHelpers) +cmake_print_variables( + CMAKE_CXX_STANDARD + CMAKE_CXX_SCAN_FOR_MODULES + CMAKE_CXX_MODULE_STD + CMAKE_CXX_COMPILER_IMPORT_STD +) # [CMAKE.SKIP_TESTS] option( @@ -42,12 +89,8 @@ option( ${PROJECT_IS_TOP_LEVEL} ) -message( - "Compiler is: ${CMAKE_CXX_COMPILER_ID} version: ${CMAKE_CXX_COMPILER_VERSION}" -) -message( - "cmake is: ${CMAKE_VERSION} modules scan : ${CMAKE_CXX_SCAN_FOR_MODULES}" -) +message(STATUS "Compiler is: ${CMAKE_CXX_COMPILER_ID} version: ${CMAKE_CXX_COMPILER_VERSION}") +message(STATUS "CMake is: ${CMAKE_VERSION} modules scan: ${CMAKE_CXX_SCAN_FOR_MODULES}") if(CMAKE_CXX_SCAN_FOR_MODULES) add_library(beman.scope) @@ -62,6 +105,8 @@ if(CMAKE_CXX_SCAN_FOR_MODULES) BASE_DIRS include FILES include/beman/scope/beman.scope.cppm ) + # prevent "not include "cxx_std_20" (or newer) among its `target_compile_features`; no C++ standard found" + target_compile_features(beman.scope PUBLIC cxx_std_23) else() add_library(beman.scope INTERFACE) target_sources( @@ -71,6 +116,7 @@ else() BASE_DIRS include FILES include/beman/scope/scope.hpp ) + target_compile_features(beman.scope INTERFACE cxx_std_20) endif() add_library(beman::scope ALIAS beman.scope) @@ -90,7 +136,7 @@ install( EXPORT beman.scope-targets FILE_SET CXX_MODULES - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILE_SET HEADERS ) @@ -116,7 +162,8 @@ if(BEMAN_SCOPE_INSTALL_CONFIG_FILE_PACKAGE) EXPORT beman.scope-targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/beman.scope NAMESPACE beman:: - CXX_MODULES_DIRECTORY cxx-modules + CXX_MODULES_DIRECTORY + cxx-modules COMPONENT beman.scope ) endif() @@ -127,5 +174,11 @@ if(BEMAN_SCOPE_BUILD_TESTS) endif() if(BEMAN_SCOPE_BUILD_EXAMPLES) + if(CLANG_TIDY_EXE) + message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") + set(CMAKE_CXX_CLANG_TIDY + "${CLANG_TIDY_EXE};-extra-arg=--Wno-error=unknown-argument" + ) + endif() add_subdirectory(examples) endif() diff --git a/cmake/appleclang-toolchain.cmake b/cmake/appleclang-toolchain.cmake index bc12103..e7a6cc4 100644 --- a/cmake/appleclang-toolchain.cmake +++ b/cmake/appleclang-toolchain.cmake @@ -16,8 +16,8 @@ include_guard(GLOBAL) -set(CMAKE_C_COMPILER clang) -set(CMAKE_CXX_COMPILER clang++) +set(CMAKE_C_COMPILER cc) +set(CMAKE_CXX_COMPILER c++) if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") set(SANITIZER_FLAGS diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1444b00..07889d3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,18 +5,18 @@ include(FetchContent) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git - GIT_TAG v3.8.0 + GIT_TAG v3.8.1 + SYSTEM + # FIXME: FIND_PACKAGE_ARGS 3.8.1 ) FetchContent_MakeAvailable(Catch2) -# module tests will only compile with gcc15 or clang20 and above +set(ALL_TESTNAMES scope_success scope_exit scope_fail unique_resource) if(CMAKE_CXX_SCAN_FOR_MODULES) - set(ALL_TESTNAMES scope_success scope_exit scope_fail unique_resource module) -else() - set(ALL_TESTNAMES scope_success scope_exit scope_fail unique_resource) + list(APPEND ALL_TESTNAMES module) endif() -message("Tests to be built: ${ALL_TESTNAMES}") +message(DEBUG "Tests to be built: ${ALL_TESTNAMES}") include(Catch) diff --git a/tests/module.test.cpp b/tests/module.test.cpp index a4b22fc..9776b3f 100644 --- a/tests/module.test.cpp +++ b/tests/module.test.cpp @@ -4,6 +4,9 @@ #include // for g++-15 the order is important -- import after includes +#ifdef HAS_STDLIB_MODULES +import std; +#endif import beman.scope; struct DummyResource { @@ -33,5 +36,4 @@ TEST_CASE("module-test", "[scope_module_test]") { REQUIRE(success_ran == true); REQUIRE(fail_ran == false); REQUIRE(cleaned == true); - }