From 7b0a9d60fa3470504fe37d57c1076da33c5ff933 Mon Sep 17 00:00:00 2001 From: ComixHe Date: Fri, 24 Oct 2025 15:21:37 +0800 Subject: [PATCH] build: Modernize CMake configuration - Bump CMake minimum version to 3.11.4 - Add project metadata and improve top-level detection - Refactor library as INTERFACE with namespace alias and remove unused static library - Optimize sanitizer configuration and extract common options - Modernize installation system with version config - Clean up code and improve maintainability Signed-off-by: ComixHe --- CMakeLists.txt | 127 +++++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 56 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2f6089..f471126 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,37 @@ -cmake_minimum_required(VERSION 3.8) -project(nanobench LANGUAGES CXX) +cmake_minimum_required(VERSION 3.11.4) + +project( + nanobench + VERSION 4.3.11 + DESCRIPTION "Simple, fast, accurate single-header microbenchmarking functionality for C++11/14/17/20" + HOMEPAGE_URL "https://github.com/martinus/nanobench" + LANGUAGES CXX) # determine whether this is a standalone project or included by other projects set(NANOBENCH_STANDALONE_PROJECT OFF) -if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + +# Modified from https://www.scivision.dev/cmake-project-is-top-level/ +if(CMAKE_VERSION VERSION_LESS 3.21) + get_property( + not_top + DIRECTORY + PROPERTY PARENT_DIRECTORY + ) + + if (NOT not_top) + set(${PROJECT_NAME}_IS_TOP_LEVEL FALSE) + else() + set(${PROJECT_NAME}_IS_TOP_LEVEL TRUE) + endif() +endif() + +if (${PROJECT_NAME}_IS_TOP_LEVEL) set(NANOBENCH_STANDALONE_PROJECT ON) endif() +add_library(${PROJECT_NAME} INTERFACE) +add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + if (NANOBENCH_STANDALONE_PROJECT) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # generate compile_commands.json @@ -17,33 +42,31 @@ if (NANOBENCH_STANDALONE_PROJECT) set(CMAKE_CXX_EXTENSIONS OFF) # configuration see .clang-tidy - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") find_program(CLANG_TIDY_PROGRAM NAMES clang-tidy) if(CLANG_TIDY_PROGRAM) set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_PROGRAM}") endif() endif() - find_program(CCACHE_PROGRAM ccache) + find_program(CCACHE_PROGRAM NAMES ccache) if(CCACHE_PROGRAM) - SET(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") - endif(CCACHE_PROGRAM) + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + endif() - add_executable(nb "") + add_executable(nb) if (NB_sanitizer) - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - # see https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#silencing-unsigned-integer-overflow - # Compile with -g and -fno-omit-frame-pointer to get proper debug information in your binary - target_compile_options(nb PRIVATE -g) - target_compile_options(nb PRIVATE -O2) - target_compile_options(nb PRIVATE -fno-omit-frame-pointer) + # Compile with -g and -fno-omit-frame-pointer to get proper debug information in your binary + set(COMMON_COMPILE_OPTIONS "-g" "-O2" "-fno-omit-frame-pointer") + set(COMMON_ASAN_COMPILE_OPTIONS "-fsanitize=address,undefined,float-divide-by-zero") + set(COMMON_ASAN_LINK_OPTIONS ${COMMON_ASAN_COMPILE_OPTIONS}) - target_compile_options(nb PRIVATE -fsanitize=address) - target_link_libraries(nb PRIVATE -fsanitize=address) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + # see https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#silencing-unsigned-integer-overflow - target_compile_options(nb PRIVATE -fsanitize=undefined,float-divide-by-zero) - target_link_libraries(nb PRIVATE -fsanitize=undefined,float-divide-by-zero) + target_compile_options(nb PRIVATE ${COMMON_COMPILE_OPTIONS} ${COMMON_ASAN_COMPILE_OPTIONS}) + target_link_options(nb PRIVATE ${COMMON_ASAN_LINK_OPTIONS}) target_compile_options(nb PRIVATE -fsanitize=integer) target_link_libraries(nb PRIVATE -fsanitize=integer) @@ -56,24 +79,18 @@ if (NANOBENCH_STANDALONE_PROJECT) src/test/tutorial_fast_v1.cpp src/test/tutorial_fast_v2.cpp PROPERTIES COMPILE_FLAGS "-fno-sanitize=integer") - - endif() - if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU") # need to use gold linker, otherwise travis gets '/usr/bin/ld: --push-state: unknown option' error target_link_libraries(nb PRIVATE -fuse-ld=gold) - target_compile_options(nb PRIVATE -g) - target_compile_options(nb PRIVATE -O2) - target_compile_options(nb PRIVATE -fno-omit-frame-pointer) + target_compile_options(nb PRIVATE ${COMMON_COMPILE_OPTIONS} ${COMMON_ASAN_COMPILE_OPTIONS}) + target_link_options(nb PRIVATE ${COMMON_ASAN_LINK_OPTIONS}) - target_compile_options(nb PRIVATE -fsanitize=undefined,float-divide-by-zero,float-cast-overflow) - target_link_libraries(nb PRIVATE -fsanitize=undefined,float-divide-by-zero,float-cast-overflow) + target_compile_options(nb PRIVATE -fsanitize=float-cast-overflow) + target_link_libraries(nb PRIVATE -fsanitize=float-cast-overflow) target_compile_options(nb PRIVATE -fsanitize=pointer-compare,pointer-subtract) target_link_libraries(nb PRIVATE -fsanitize=pointer-compare,pointer-subtract) - - target_compile_options(nb PRIVATE -fsanitize=address) - target_link_libraries(nb PRIVATE -fsanitize=address) endif() endif() @@ -82,28 +99,22 @@ if (NANOBENCH_STANDALONE_PROJECT) target_sources_local(nb PUBLIC .clang-tidy) - include(GNUInstallDirs) - set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/cmake) - set(INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}) - - # Install library target - add_library(nanobench STATIC ${PROJECT_SOURCE_DIR}/src/test/app/nanobench.cpp) - target_compile_features(nanobench PUBLIC cxx_std_11) - target_include_directories(nanobench - PUBLIC - $ - $ - ) - install( - TARGETS nanobench - EXPORT install_targets - LIBRARY DESTINATION ${INSTALL_LIBDIR} - ARCHIVE DESTINATION ${INSTALL_LIBDIR} + set(INSTALL_HEADERS_DIR ${CMAKE_INSTALL_INCLUDEDIR}) + set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) + + target_include_directories(${PROJECT_NAME} + INTERFACE + $ + $ ) + # Install headers + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/include/nanobench.h DESTINATION ${INSTALL_HEADERS_DIR}) + # Install targets file - install(EXPORT install_targets + install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets) + install(EXPORT ${PROJECT_NAME}Targets FILE ${PROJECT_NAME}Targets.cmake NAMESPACE @@ -112,23 +123,27 @@ if (NANOBENCH_STANDALONE_PROJECT) ${INSTALL_CONFIGDIR} ) - # Install ${PROJECT_NAME}Config.cmake + # Install ${PROJECT_NAME}Config.cmake and ${PROJECT_NAME}ConfigVersion.cmake include(CMakePackageConfigHelpers) + + write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion + ) + configure_package_config_file( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake - INSTALL_DESTINATION ${INSTALL_CONFIGDIR} + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake DESTINATION ${INSTALL_CONFIGDIR} ) - - # Install headers - install(FILES src/include/nanobench.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) else() - add_library(nanobench STATIC ${PROJECT_SOURCE_DIR}/src/test/app/nanobench.cpp) - add_library(nanobench::nanobench ALIAS nanobench) - set_property(TARGET nanobench PROPERTY CXX_STANDARD 17) - target_include_directories(nanobench PUBLIC ${PROJECT_SOURCE_DIR}/src/include) + set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17) + target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src/include) endif()