c++cmakegitlabcicdctest

Separating of tests build form application build in CI/CD without rebuilding


I have a project with files:

main.cpp - application
sum.h
sum.cpp
tester.cpp - tester application

I build it with CMake, CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set (ProjectName hello)
project(hello VERSION 1.0)
set(SOURCES sum.h sum.cpp main.cpp)
add_executable(${ProjectName} ${SOURCES})

enable_testing()
add_executable(tester sum.h sum.cpp tester.cpp)
add_test(Tester tester)

Then I set up a CI/CD on gitlab:

image: gcc

build:
  stage: build
  before_script:
   - apt update && apt -y install make cmake libcrypto++-dev
  script:
    - cd SimpleCiCdForCpp
    - mkdir build
    - cd build
    - cmake ..
    - make
    - ls
  artifacts:
    paths:
      - SimpleCiCdForCpp/build/hello
      - SimpleCiCdForCpp/build/tester

test:
  stage: test
  before_script:
   - apt update && apt -y install make cmake libcrypto++-dev
  script:
    - ls
    - cd SimpleCiCdForCpp
    - cd build
    - cmake ..
    - make
    - ctest

Everything works - I have 2 applications: the main one and the tester and the tests pass. The problem is that I have to build everything on Build stage and on Testing stage, otherwise I end up with empty testing config for ctest Is there any good practice to separate testing projects from main applications?


Solution

  • Your CMAkeLists.txt may look like this:

    cmake_minimum_required(VERSION 3.10)
    project(hello VERSION 1.0)
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    include(CTest) # Sets BUILD_TESTING=0 by default
    
    # Do not build twice.
    add_library(sum sum.cpp sum.h)
    
    # There is already PROJECT_NAME CMake variable.
    add_executable(${PROJECT_NAME} main.cpp)
    target_link_libraries(${PROJECT_NAME} PRIVATE sum)
    
    # Do not use if not needed!
    if(BUILD_TESTING)
      add_executable(tester tester.cpp)
      target_link_libraries(tester PRIVATE sum)
      # Use same name for test and executable.
      add_test(COMMAND tester NAME tester)
    endif()
    

    Then:

    build:
        - cmake -S. -Bbuild -DBUILD_TESTING=0
        - cmake --build build
      artifacts:
        paths:
          # Cache the... cache, so that you don't rebuild!
          - SimpleCiCdForCpp/build
    
    test:
        - cmake -S. -Bbuild -DBUILD_TESTING=1
        - cmake --build build
        # Newest syntax.
        - ctest --test-dir build