zoukankan      html  css  js  c++  java
  • cmake设置单元测试目标

    目录结构

    .
    |-- cmake
    |   |-- CompilerSettings.cmake
    |   |-- Options.cmake
    |   |-- ProjectBoost.cmake
    |   `-- UseOpenSSL.cmake
    |-- CMakeLists.txt
    |-- hello-cpp
    |   |-- CMakeLists.txt
    |   `-- main.cpp
    |-- libfoo
    |   |-- CMakeLists.txt
    |   |-- Foo.cpp
    |   `-- Foo.h
    `-- test
        |-- CMakeLists.txt
        |-- test-hello-cpp
        |   `-- main.cpp
        `-- test-libfoo
            `-- Foo.cpp
    

    根目录cmake

    # cmake版本要求
    cmake_minimum_required(VERSION 3.7)
    
    # 项目信息
    project(hello-cpp
            VERSION 1.0.0
            LANGUAGES CXX)
    
    # 添加模块目录(CMAKE_CURRENT_SOURCE_DIR表示当前CMakeList.txt的路径)
    list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
    
    # 基本设置
    include(Options)
    include(CompilerSettings)
    print_config()
    
    # 下载安装依赖库
    include(UseOpenSSL)
    include(ProjectBoost)
    
    # 添加子目录
    add_subdirectory(libfoo)
    add_subdirectory(${PROJECT_NAME})
    
    # 构建并运行单元测试
    if (WITH_TESTS)
        enable_testing()
        add_subdirectory(test)
    endif()
    

    cmake目录

    • Options.cmake:用于指定编译特性选项
    # 构建类型,支持Debug Release RelWithDebInfo MinSizeRel,默认为RelWithDebInfo
    if (NOT CMAKE_BUILD_TYPE)
        set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
            "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
    endif()
    
    # C++标准,使用C++11
    set(CMAKE_CXX_STANDARD 11)
    
    # 是否构建代码覆盖率检测任务
    option(WITH_COVERAGE "Test code coverage" OFF)
    
    # 是否构建并运行单元测试
    option(WITH_TESTS "Build and run tests" ON)
    if (WITH_COVERAGE)
        set(WITH_TESTS ON)
    endif()
    
    # 显示所有配置信息
    macro(print_config)
        message("")
        message("------------------------------------------------------------------------")
        message("-- Configuring ${PROJECT_NAME} ${PROJECT_VERSION}${VERSION_SUFFIX}")
        message("------------------------------------------------------------------------")
        message("-- CMake              Cmake version and location   ${CMAKE_VERSION} (${CMAKE_COMMAND})")
        message("-- Compiler           C++ compiler version         ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
        message("-- TARGET_PLATFORM    Target platform              ${CMAKE_SYSTEM_NAME}")
        message("-- CMAKE_BUILD_TYPE   Build type                   ${CMAKE_BUILD_TYPE}")
        message("-- CMAKE_CXX_STANDARD C++ standard                 ${CMAKE_CXX_STANDARD}")
        message("-- WITH_COVERAGE      Test code coverage           ${WITH_COVERAGE}")
        message("-- WITH_TESTS         Build and run tests          ${WITH_TESTS}")
        message("------------------------------------------------------------------------")
        message("")
    endmacro()
    
    • CompilerSettings.cmake:用于指定编译选项
    # 添加根目录到头文件搜索目录
    include_directories(BEFORE ${PROJECT_SOURCE_DIR})
    
    # 设置可执行文件输出路径
    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
    
    # 设置编译器选项
    if (${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
        # gcc
        if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
            message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.8+. Current is ${CMAKE_CXX_COMPILER_VERSION}.")
        endif()
    
        # 各个编译模式下共用的编译选项
        set(CMAKE_CXX_FLAGS "-Wall -Wextra -pthread")
    
        if (WITH_COVERAGE)
            set(CMAKE_CXX_FLAGS "-g --coverage ${CMAKE_CXX_FLAGS}")
            find_program(LCOV_TOOL lcov)
            message(STATUS "lcov tool: ${LCOV_TOOL}")
            if (LCOV_TOOL)
                add_custom_target(coverage
                    COMMAND ${LCOV_TOOL} -o ${CMAKE_BINARY_DIR}/coverage.info.in -c -d ${CMAKE_BINARY_DIR}/
                    COMMAND ${LCOV_TOOL} -r ${CMAKE_BINARY_DIR}/coverage.info.in '/usr*' '${CMAKE_SOURCE_DIR}/deps*' '${CMAKE_SOURCE_DIR}/test*' -o ${CMAKE_BINARY_DIR}/coverage.info
                    COMMAND genhtml -q -o ${CMAKE_BINARY_DIR}/CodeCoverage ${CMAKE_BINARY_DIR}/coverage.info)
            else ()
                message(FATAL_ERROR "Can't find lcov tool. Please install lcov")
            endif()
        endif()
    
        # 各编译模式专有的编译选项
        set(CMAKE_CXX_FLAGS_DEBUG          "-Og -g")
        set(CMAKE_CXX_FLAGS_MINSIZEREL     "-Os -DNDEBUG")
        set(CMAKE_CXX_FLAGS_RELEASE        "-O3 -DNDEBUG")
        set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
    else()
        message(FATAL_ERROR "Your compiler is not supported.")
    endif()
    
    • ProjectBoost.cmake:下载编译boost库
    # 导入插件
    include(ExternalProject)
    include(ProcessorCount)
    
    # 获取cpu核数
    ProcessorCount(CORES)
    if(CORES EQUAL 0)
      set(CORES 1)
    endif()
    
    # 配置命令
    set(BOOST_BOOTSTRAP_COMMAND ./bootstrap.sh)
    # 构建命令
    set(BOOST_BUILD_TOOL ./b2)
    # 编译选项
    set(BOOST_CXXFLAGS "cxxflags=-std=c++11")
    
    # 下载构建安装依赖库
    ExternalProject_Add(boost
        # 项目根目录
        PREFIX ${CMAKE_SOURCE_DIR}/deps
        # 下载名
        DOWNLOAD_NAME boost_1_74_0.tar.bz2
        # 下载链接(支持多源下载)
        URL https://dl.bintray.com/boostorg/release/1.74.0/source/boost_1_74_0.tar.bz2
        # sha256哈希值校验
        URL_HASH SHA256=83bfc1507731a0906e387fc28b7ef5417d591429e51e788417fe9ff025e116b1
        # 在源码中构建
        BUILD_IN_SOURCE 1
        # 配置命令
        CONFIGURE_COMMAND ${BOOST_BOOTSTRAP_COMMAND}
        # 构建命令
        BUILD_COMMAND ${BOOST_BUILD_TOOL} stage
                      ${BOOST_CXXFLAGS}
                      threading=multi
                      variant=release
                      link=static
                      --layout=system
                      --with-date_time
                      --with-regex
                      --with-serialization
                      --with-system
                      --with-test
                      -j${CORES}
        # 安装命令
        INSTALL_COMMAND ""
        # 日志记录
        LOG_CONFIGURE 1
        LOG_BUILD 1
        LOG_INSTALL 1
    )
    
    # boost库头文件目录和库目录
    ExternalProject_Get_Property(boost SOURCE_DIR)
    set(BOOST_INCLUDE_DIR ${SOURCE_DIR})
    set(BOOST_LIBRARY_PREFIX ${SOURCE_DIR}/stage/lib/${CMAKE_STATIC_LIBRARY_PREFIX})
    
    # Boost::Algorithm库
    add_library(Boost::Algorithm INTERFACE IMPORTED GLOBAL)
    set_property(TARGET Boost::Algorithm PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${BOOST_INCLUDE_DIR})
    add_dependencies(Boost::Algorithm boost)
    
    # Boost::ASIO库
    add_library(Boost::ASIO INTERFACE IMPORTED GLOBAL)
    set_property(TARGET Boost::ASIO PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${BOOST_INCLUDE_DIR})
    set_property(TARGET Boost::ASIO PROPERTY INTERFACE_LINK_LIBRARIES Boost::DateTime Boost::Regex Boost::Serialization
                                                                      Boost::System OpenSSL::SSL)
    add_dependencies(Boost::ASIO boost)
    
    # Boost::DateTime库
    add_library(Boost::DateTime STATIC IMPORTED GLOBAL)
    set_property(TARGET Boost::DateTime PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${BOOST_INCLUDE_DIR})
    set_property(TARGET Boost::DateTime PROPERTY IMPORTED_LOCATION ${BOOST_LIBRARY_PREFIX}boost_date_time${CMAKE_STATIC_LIBRARY_SUFFIX})
    set_property(TARGET Boost::DateTime PROPERTY INTERFACE_LINK_LIBRARIES Boost::Serialization)
    add_dependencies(Boost::DateTime boost)
    
    # Boost::Functional库
    add_library(Boost::Functional INTERFACE IMPORTED GLOBAL)
    set_property(TARGET Boost::Functional PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${BOOST_INCLUDE_DIR})
    add_dependencies(Boost::Functional boost)
    
    # Boost::Multiprecision库
    add_library(Boost::Multiprecision INTERFACE IMPORTED GLOBAL)
    set_property(TARGET Boost::Multiprecision PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${BOOST_INCLUDE_DIR})
    add_dependencies(Boost::Multiprecision boost)
    
    # Boost::Regex库
    add_library(Boost::Regex STATIC IMPORTED GLOBAL)
    set_property(TARGET Boost::Regex PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${BOOST_INCLUDE_DIR})
    set_property(TARGET Boost::Regex PROPERTY IMPORTED_LOCATION ${BOOST_LIBRARY_PREFIX}boost_regex${CMAKE_STATIC_LIBRARY_SUFFIX})
    add_dependencies(Boost::Regex boost)
    
    # Boost::Serialization库
    add_library(Boost::Serialization STATIC IMPORTED GLOBAL)
    set_property(TARGET Boost::Serialization PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${BOOST_INCLUDE_DIR})
    set_property(TARGET Boost::Serialization PROPERTY IMPORTED_LOCATION ${BOOST_LIBRARY_PREFIX}boost_serialization${CMAKE_STATIC_LIBRARY_SUFFIX})
    add_dependencies(Boost::Serialization boost)
    
    # Boost::System库
    add_library(Boost::System STATIC IMPORTED GLOBAL)
    set_property(TARGET Boost::System PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${BOOST_INCLUDE_DIR})
    set_property(TARGET Boost::System PROPERTY IMPORTED_LOCATION ${BOOST_LIBRARY_PREFIX}boost_system${CMAKE_STATIC_LIBRARY_SUFFIX})
    add_dependencies(Boost::System boost)
    
    # Boost::UnitTestFramework库
    add_library(Boost::UnitTestFramework STATIC IMPORTED GLOBAL)
    set_property(TARGET Boost::UnitTestFramework PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${BOOST_INCLUDE_DIR})
    set_property(TARGET Boost::UnitTestFramework PROPERTY IMPORTED_LOCATION ${BOOST_LIBRARY_PREFIX}boost_unit_test_framework${CMAKE_STATIC_LIBRARY_SUFFIX})
    add_dependencies(Boost::UnitTestFramework boost)
    
    # 取消临时定义
    unset(SOURCE_DIR)
    
    • UseOpenSSL.cmake:ASIO中的ssl特性依赖openssl库:
    # OpenSSL::SSL库
    add_library(OpenSSL::SSL INTERFACE IMPORTED GLOBAL)
    set_property(TARGET OpenSSL::SSL PROPERTY INTERFACE_LINK_LIBRARIES -lssl)
    

    hello-cpp模块cmake

    # 获取源文件和头文件列表
    file(GLOB SRCS "*.cpp")
    file(GLOB HEADERS "*.h")
    
    # 添加可执行目标
    add_executable(${PROJECT_NAME} ${SRCS} ${HEADERS})
    
    # 添加依赖库
    target_link_libraries(${PROJECT_NAME} PUBLIC libfoo)
    

    libfoo的cmake:

    # 获取源文件和头文件列表
    file(GLOB SRCS "*.cpp")
    file(GLOB HEADERS "*.h")
    
    # 添加可执行目标
    add_executable(${PROJECT_NAME} ${SRCS} ${HEADERS})
    
    # 添加依赖库
    target_link_libraries(${PROJECT_NAME} PUBLIC libfoo)
    

    test模块cmake

    # 获取源文件和头文件列表
    file(GLOB_RECURSE SRCS "*.cpp")
    file(GLOB_RECURSE HEADERS "*.h")
    
    # 添加可执行目标
    add_executable(test-${PROJECT_NAME} ${SRCS} ${HEADERS})
    
    # 添加依赖库
    target_link_libraries(test-${PROJECT_NAME} PUBLIC Boost::UnitTestFramework)
    target_link_libraries(test-${PROJECT_NAME} PUBLIC libfoo)
    
    # 添加测试目标
    add_test(NAME test-${PROJECT_NAME} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ./bin/test-${PROJECT_NAME})
    
    # 自动运行测试
    add_custom_command(TARGET test-${PROJECT_NAME} POST_BUILD WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ./bin/test-${PROJECT_NAME})
    

    test模块main函数:

    #define BOOST_TEST_MODULE XX_Tests
    #include <boost/test/unit_test.hpp>
    

    test模块单元测试:

    #include <boost/test/unit_test.hpp>
    #include <libfoo/Foo.h>
    
    BOOST_AUTO_TEST_SUITE(FooTests)
    
    BOOST_AUTO_TEST_CASE(sumTest)
    {
        BOOST_CHECK(10 == sum(4, 6));
    }
    
    BOOST_AUTO_TEST_SUITE_END()
    
  • 相关阅读:
    带下拉子菜单的导航菜单
    如何使用myFocus插件制作焦点图效果
    将博客搬至CSDN
    《转》二进制与三进制的那些趣题
    二叉树遍历 (前序 层次 == 深度 广度) 层次遍历
    数组全排列 knuth 分解质因数
    堆排序
    双向快速排序
    二路归并排序
    字符串的排列
  • 原文地址:https://www.cnblogs.com/HachikoT/p/14170125.html
Copyright © 2011-2022 走看看