I have a library, and inside the library are two implementations of how it works, one is a GPIO wrapper and the other is a simulator for when the machine being developed on does not have real GPIO pins.
So far the library is set up that an option is specified when it is built choosing to to add_subdirectory() on either of the options (similar to this cmake tutorial). This all works fine (compiles and runs as expected with manual tests).
My issue is that now I would like to add unit tests, ideally these should test the library with both build configurations (or just the simulator). But, as the tests are a subdirectory of the overall GPIO project, the library is always built first and so the tests cannot specify the build options.
I guess my questions are:
What can I do to cause the library to be built a certain way for the tests only?
Have I set my project up correctly? (Are my tests in the correct place? They work with the structure for my other projects, but perhaps this situation highlights a problem)
Is there a way to cause the library to be built in a specific way for testing?
Should I be using build options for a library, or is there a different mechanism that would prevent this issue?
I have stripped the project back to the minimum required to show the problem:
CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(GPIOProj CXX)
add_library(${PROJECT_NAME})
if(USE_SIMULATOR)
add_subdirectory(gpioSimulator)
else()
add_subdirectory(gpioWrapper)
endif()
target_include_directories(${PROJECT_NAME} PUBLIC
.)
add_subdirectory(tests)
Folder structure:
gpio-+
|
-CMakeLists.txt
|
-gpioSimulator
| |
| - misc implementation
|
-gpioWrapper
| |
| _ misc implementation
|
-tests
|
-tests.cpp
-CMakeLists.txt
tests/CMakeLists.txt:
cmake_minimum_required(VERSION 3.23)
project(tests)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED On)
enable_testing()
add_executable(
${PROJECT_NAME}
${CMAKE_CURRENT_LIST_DIR}
tests.cpp
)
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".exe")
set(USE_GPIO_SIMULATOR On) # This wants to be set for GPIOProj, but this does not build the library
target_link_libraries(${PROJECT_NAME} PRIVATE GPIOProj)
include(GoogleTest)
gtest_discover_tests(${PROJECT_NAME})
I know that I can add a second library in CMakeLists.txt and add subdirectories to that and get my desired result, but then I have to maintain two libraries in CMake. I also could access the code files needed by the test directly, but then it wouldn't be testing the library. I am not sure on what else to do!
The best method I have found so far is to use CMake Presets. This allows me to set build options in a preset to use specifically for testing. (I also added a ENABLE_TESTS variable that excludes the tests from the build when not set). For each implementation of GPIO I want to build/test for I create a new testing preset for that.