diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e843d1..a13e356 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,27 +1,85 @@ cmake_minimum_required(VERSION 3.18) -project(CLoveUnit LANGUAGES C) +set(CLOVE_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) +list(INSERT CMAKE_MODULE_PATH 0 ${CLOVE_SOURCE_DIR}/cmake/modules) + +# Extract CLOVE_VERSION from header file +set(CLOVE_VERSION_REGEX "#define __CLOVE_VERSION_.*[ \t]+(.+)") +file(STRINGS "${CLOVE_SOURCE_DIR}/clove-unit.h" CLOVE_VERSION REGEX ${CLOVE_VERSION_REGEX}) +list(TRANSFORM CLOVE_VERSION REPLACE ${CLOVE_VERSION_REGEX} "\\1") +string(JOIN "." CLOVE_VERSION ${CLOVE_VERSION}) + +# Configure Project +project( + CLoveUnit + VERSION ${CLOVE_VERSION} + DESCRIPTION "Single-header Unit Testing framework for C (interoperable with C++) with test autodiscovery feature" + HOMEPAGE_URL "https://github.com/fdefelici/clove-unit" + LANGUAGES C +) + +include(JoinPaths) +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) + +join_paths(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" clove-unit ${PROJECT_VERSION}) + +# Library Target definition and configuration add_library(clove-unit INTERFACE) -target_include_directories(clove-unit INTERFACE "${CMAKE_CURRENT_LIST_DIR}") +add_library(clove-unit::clove-unit ALIAS clove-unit) + +target_include_directories( + clove-unit INTERFACE + $ + $ +) + target_compile_features(clove-unit INTERFACE c_std_11) -#[[ -add_subdirectory(tests/functs) -if (DEFINED CLOVE_CMAKE__CI_TRIGGERED) - add_subdirectory(tests/stricts/clove-c) - add_subdirectory(tests/stricts/clove-cpp) - add_subdirectory(examples/clove101) - add_subdirectory(examples/clovepp) -endif() +# Install command stuffs for enabling find_package usage +install( + TARGETS clove-unit + EXPORT clove-unit-targets + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +write_basic_package_version_file( + clove-unit-config-version.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion +) + +configure_package_config_file( + ${CLOVE_SOURCE_DIR}/cmake/in/clove-unit-config.cmake.in + clove-unit-config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake +) + +install( + FILES ${CLOVE_SOURCE_DIR}/clove-unit.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +install( + FILES + ${PROJECT_BINARY_DIR}/clove-unit-config.cmake + ${PROJECT_BINARY_DIR}/clove-unit-config-version.cmake + DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake +) + +install( + EXPORT clove-unit-targets + #NAMESPACE clove-unit:: + DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake +) + +export(PACKAGE clove-unit) -if (DEFINED CLOVE_CMAKE__ENABLE_PERFS) -add_subdirectory(tests/perfs) -endif() -]] #[[ In case this is the root project add dev targets (Development mode). To avoid targets pollution when using FetchContent were only the target library is required + Note: PROJECT_IS_TOP_LEVEL cmake variable exists in version 3.21+ ]] if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) include(CTest) @@ -42,4 +100,4 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) add_subdirectory(tests/perfs) endif() -endif() \ No newline at end of file +endif() diff --git a/README.md b/README.md index 21ac741..b3c2bf9 100644 --- a/README.md +++ b/README.md @@ -70,9 +70,9 @@ Then remember to properly configure your compiler include paths. * [Conan](https://conan.io): read [here](https://conan.io/center/recipes/clove-unit) for details on how to import it. ### Using CMake -In case you still need dependency management, but you want to avoid Package Manager configuration complexity, you can use standard mechansim provided by `CMake` such as [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) and [add_subdirectory](https://cmake.org/cmake/help/latest/command/add_subdirectory.html). +In case you still need dependency management, but you want to avoid Package Manager configuration complexity, you can use standard mechansim provided by `CMake` such as [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html), [add_subdirectory](https://cmake.org/cmake/help/latest/command/add_subdirectory.html) and [find_package](https://cmake.org/cmake/help/latest/command/find_package.html). -> CMake library is named `clove-unit` +> NOTE: CMake library is named `clove-unit` Here a few examples: @@ -94,7 +94,7 @@ Here a few examples: target_link_libraries(tests clove-unit) ``` -* [add_subdirectory](https://cmake.org/cmake/help/latest/command/add_subdirectory.html) +* **add_subdirectory** First download `CLove-Unit` repository and then point properly to it like this: @@ -108,6 +108,29 @@ Here a few examples: target_link_libraries(tests clove-unit) ``` +* **find_package** + + First download `CLove-Unit` repository and then run cmake install command on it. + + Package will be installed in at following path: `` + + Eventually you may want to customize [CMAKE_INSTALL_PREFIX](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html) variable to override cmake default installation path for packages. + + + Then use the package as follow: + ```cmake + cmake_minimum_required(VERSION 3.18) + project(TestProject C) + + find_package(clove-unit REQUIRED PATHS ) + + # or more strict + # find_package(clove-unit EXACT REQUIRED PATHS ) + + add_executable(tests ) + target_link_libraries(tests clove-unit) + ``` + ## How It Works `CLove-Unit` is built upon these fundamental concepts: diff --git a/cmake/in/clove-unit-config.cmake.in b/cmake/in/clove-unit-config.cmake.in new file mode 100644 index 0000000..6d9ec93 --- /dev/null +++ b/cmake/in/clove-unit-config.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +set(CLOVE_VERSION "@PROJECT_VERSION@") +include("${CMAKE_CURRENT_LIST_DIR}/clove-unit-targets.cmake") +check_required_components("@PROJECT_NAME@") \ No newline at end of file diff --git a/cmake/modules/JoinPaths.cmake b/cmake/modules/JoinPaths.cmake new file mode 100644 index 0000000..ce80aff --- /dev/null +++ b/cmake/modules/JoinPaths.cmake @@ -0,0 +1,23 @@ +# This module provides function for joining paths +# known from most languages +# +# SPDX-License-Identifier: (MIT OR CC0-1.0) +# Copyright 2020 Jan Tojnar +# https://github.com/jtojnar/cmake-snips +# +# Modelled after Python’s os.path.join +# https://docs.python.org/3.7/library/os.path.html#os.path.join +# Windows not supported +function(join_paths joined_path first_path_segment) + set(temp_path "${first_path_segment}") + foreach(current_segment IN LISTS ARGN) + if(NOT ("${current_segment}" STREQUAL "")) + if(IS_ABSOLUTE "${current_segment}") + set(temp_path "${current_segment}") + else() + set(temp_path "${temp_path}/${current_segment}") + endif() + endif() + endforeach() + set(${joined_path} "${temp_path}" PARENT_SCOPE) +endfunction() \ No newline at end of file