|
11 | 11 | # |
12 | 12 | ################################################################## |
13 | 13 |
|
| 14 | +# define a custom property to track dependencies on CFE module targets. |
| 15 | +# users should not typically maniplate this directly |
| 16 | +define_property(TARGET PROPERTY CFE_MODULE_DEPENDENCIES |
| 17 | + BRIEF_DOCS |
| 18 | + "A set of CFE module dependencies" |
| 19 | + FULL_DOCS |
| 20 | + "This is a CFE-specific target property that is added to CFE modules that contains the module dependencies" |
| 21 | +) |
| 22 | + |
14 | 23 |
|
15 | 24 | ################################################################## |
16 | 25 | # |
@@ -97,6 +106,38 @@ function(add_cfe_app APP_NAME APP_SRC_FILES) |
97 | 106 |
|
98 | 107 | endfunction(add_cfe_app) |
99 | 108 |
|
| 109 | +################################################################## |
| 110 | +# |
| 111 | +# FUNCTION: add_cfe_app_dependency |
| 112 | +# |
| 113 | +# Adds a library dependency to a previously-created |
| 114 | +# app/library target |
| 115 | +# |
| 116 | +# it adds the interface include directories and compile definitions |
| 117 | +# of the dependency into the compilation for the module. |
| 118 | +# |
| 119 | +function(add_cfe_app_dependency MODULE_NAME DEPENDENCY_MODULE) |
| 120 | + |
| 121 | + # assemble a list of include directories and compile definitions |
| 122 | + set(INCLUDE_LIST) |
| 123 | + set(COMPILE_DEF_LIST) |
| 124 | + foreach(DEP ${DEPENDENCY_MODULE} ${ARGN}) |
| 125 | + list(APPEND INCLUDE_LIST "$<TARGET_PROPERTY:${DEPENDENCY_MODULE},INTERFACE_INCLUDE_DIRECTORIES>") |
| 126 | + list(APPEND COMPILE_DEF_LIST "$<TARGET_PROPERTY:${DEPENDENCY_MODULE},INTERFACE_COMPILE_DEFINITIONS>") |
| 127 | + endforeach() |
| 128 | + |
| 129 | + target_include_directories(${MODULE_NAME} PUBLIC |
| 130 | + ${INCLUDE_LIST} |
| 131 | + ) |
| 132 | + target_compile_definitions(${MODULE_NAME} PUBLIC |
| 133 | + ${COMPILE_DEF_LIST} |
| 134 | + ) |
| 135 | + |
| 136 | + # append to the custom property to track this dependency (this helpful for UT) |
| 137 | + set_property(TARGET ${MODULE_NAME} APPEND PROPERTY CFE_MODULE_DEPENDENCIES ${DEPENDENCY_MODULE} ${ARGN}) |
| 138 | + |
| 139 | +endfunction(add_cfe_app_dependency) |
| 140 | + |
100 | 141 | ################################################################## |
101 | 142 | # |
102 | 143 | # FUNCTION: add_cfe_tables |
@@ -175,47 +216,194 @@ endfunction(add_cfe_tables) |
175 | 216 |
|
176 | 217 | ################################################################## |
177 | 218 | # |
178 | | -# FUNCTION: add_unit_test_lib |
| 219 | +# FUNCTION: add_cfe_coverage_dependency |
| 220 | +# |
| 221 | +# Adds a stub library dependency to a previously-created |
| 222 | +# coverage test runner target |
179 | 223 | # |
180 | | -# Add a library for unit testing. This is basically the same as the |
181 | | -# normal CMake "add_library" but enables the code coverage compiler options. |
| 224 | +# If a unit under test calls functions provided by another unit |
| 225 | +# (such as a library) then the stubs from that library will be |
| 226 | +# added to the LINK_LIBRARIES of the coverage test. |
182 | 227 | # |
183 | | -function(add_unit_test_lib UT_NAME UT_SRCS) |
184 | | - add_library(utl_${UT_NAME} STATIC ${UT_SRCS} ${ARGN}) |
185 | | - set_target_properties(utl_${UT_NAME} PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -pg --coverage") |
186 | | -endfunction(add_unit_test_lib) |
| 228 | +function(add_cfe_coverage_dependency MODULE_NAME UNIT_NAME DEPENDENCY_MODULE) |
| 229 | + |
| 230 | + # the stub library correlating to the module should be named: |
| 231 | + # coverage-${MODULE_NAME}-stubs |
| 232 | + # (assuming it was added by the add_cfe_coverage_stubs above) |
| 233 | + set(DEP_LIST) |
| 234 | + foreach(DEP ${DEPENDENCY_MODULE} ${ARGN}) |
| 235 | + list(APPEND DEP_LIST "coverage-${DEP}-stubs") |
| 236 | + endforeach() |
| 237 | + |
| 238 | + target_link_libraries(coverage-${MODULE_NAME}-${UNIT_NAME}-testrunner |
| 239 | + ${DEP_LIST} |
| 240 | + ) |
| 241 | + |
| 242 | +endfunction(add_cfe_coverage_dependency) |
| 243 | + |
187 | 244 |
|
188 | 245 | ################################################################## |
189 | 246 | # |
190 | | -# FUNCTION: add_unit_test_exe |
| 247 | +# FUNCTION: add_cfe_coverage_test |
| 248 | +# |
| 249 | +# Add executable target for coverage testing. This builds the target |
| 250 | +# units with extra compiler flags for coverage instrumentation, along with |
| 251 | +# a "testrunner" executable to run the tests. It also registers |
| 252 | +# that testrunner with ctest via the add_test() function. |
| 253 | +# |
| 254 | +# NOTE: The first argument (MODULE_NAME) must match the name that was previously |
| 255 | +# passed to the add_cfe_app() function - as this references that previous |
| 256 | +# target to use the same compile definitions and include paths. |
191 | 257 | # |
192 | | -# Create unit test executable. This links the UT main executive with |
193 | | -# a library that is placed under test (created via add_unit_test_lib) |
194 | | -# It also registers the final executable target with ctest so it will |
195 | | -# be run during the "make test" target or when ctest is run. |
| 258 | +# The executable target name follows the pattern: |
| 259 | +# "coverage-${MODULE_NAME}-${UNIT_NAME}-testrunner" |
196 | 260 | # |
197 | | -function(add_unit_test_exe UT_NAME UT_SRCS) |
198 | | - add_executable(${UT_NAME} ${utexec_MISSION_DIR}/src/utexec.c ${UT_SRCS} ${ARGN}) |
| 261 | +# The calling script may call target_link_libraries() (or other target functions) |
| 262 | +# to customize this target as needed. |
| 263 | +# |
| 264 | +function(add_cfe_coverage_test MODULE_NAME UNIT_NAME TESTCASE_SRC UT_SRCS) |
| 265 | + |
| 266 | + # A consistent name convention for all targets generated by this funtion |
| 267 | + set(TEST_NAME "coverage-${MODULE_NAME}-${UNIT_NAME}") |
| 268 | + set(OBJECT_TARGET "${TEST_NAME}-object") |
| 269 | + set(RUNNER_TARGET "${TEST_NAME}-testrunner") |
| 270 | + |
| 271 | + # Compile the source unit(s) under test as a separate library |
| 272 | + # This is done so that special coverage-specific compile flags can be used on these files |
| 273 | + add_library(${OBJECT_TARGET} OBJECT |
| 274 | + ${UT_SRCS} |
| 275 | + ) |
199 | 276 |
|
200 | | - get_target_property(UTCDEFS ${UT_NAME} COMPILE_DEFINITIONS) |
201 | | - list(APPEND UTCDEFS "DEFAULT_REF_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"") |
| 277 | + # Apply the UT_COVERAGE_COMPILE_FLAGS to the units under test |
| 278 | + # This should enable coverage analysis on platforms that support this |
| 279 | + target_compile_options(${OBJECT_TARGET} PRIVATE |
| 280 | + ${UT_COVERAGE_COMPILE_FLAGS} |
| 281 | + ) |
| 282 | + |
| 283 | + # Include the same set of include dirs/definitions that is used from the app target |
| 284 | + target_include_directories(${OBJECT_TARGET} PUBLIC |
| 285 | + $<TARGET_PROPERTY:${MODULE_NAME},INCLUDE_DIRECTORIES> |
| 286 | + ) |
| 287 | + target_compile_definitions(${OBJECT_TARGET} PUBLIC |
| 288 | + $<TARGET_PROPERTY:${MODULE_NAME},COMPILE_DEFINITIONS> |
| 289 | + ) |
| 290 | + |
| 291 | + # Compile a test runner application, which contains the |
| 292 | + # actual coverage test code (test cases) and the unit under test |
| 293 | + add_executable(${RUNNER_TARGET} |
| 294 | + ${TESTCASE_SRC} |
| 295 | + $<TARGET_OBJECTS:${OBJECT_TARGET}> |
| 296 | + ) |
202 | 297 |
|
203 | | - get_target_property(UTCFLAGS ${UT_NAME} COMPILE_FLAGS) |
204 | | - if (UTCFLAGS STREQUAL "UTCFLAGS-NOTFOUND") |
205 | | - set(UTCFLAGS) |
206 | | - endif() |
207 | | - set(UTCFLAGS "${UTCFLAGS} -I${utexec_MISSION_DIR}/inc -I${CMAKE_CURRENT_SOURCE_DIR}") |
| 298 | + # Include the same set of include dirs/definitions that is used from the app target |
| 299 | + target_include_directories(${RUNNER_TARGET} PUBLIC |
| 300 | + $<TARGET_PROPERTY:${MODULE_NAME},INCLUDE_DIRECTORIES> |
| 301 | + ) |
| 302 | + target_compile_definitions(${RUNNER_TARGET} PUBLIC |
| 303 | + $<TARGET_PROPERTY:${MODULE_NAME},COMPILE_DEFINITIONS> |
| 304 | + ) |
| 305 | + |
| 306 | + # This also needs to be linked with UT_COVERAGE_LINK_FLAGS (for coverage) |
| 307 | + # This is also linked with any other stub libraries needed, |
| 308 | + # as well as the UT assert framework |
| 309 | + target_link_libraries(${RUNNER_TARGET} |
| 310 | + ${UT_COVERAGE_LINK_FLAGS} |
| 311 | + ut_cfe-core_stubs |
| 312 | + ut_assert |
| 313 | + ) |
208 | 314 |
|
209 | | - get_target_property(UTLFLAGS ${UT_NAME} LINK_FLAGS) |
210 | | - if (UTLFLAGS STREQUAL "UTLFLAGS-NOTFOUND") |
211 | | - set(UTLFLAGS) |
| 315 | + # for whatever app/lib dependencies the real FSW app had, the unit test |
| 316 | + # should have the same dependencies but on the stubs instead. |
| 317 | + get_target_property(MODULE_DEPENDENCIES ${MODULE_NAME} CFE_MODULE_DEPENDENCIES) |
| 318 | + if (MODULE_DEPENDENCIES) |
| 319 | + add_cfe_coverage_dependency(${MODULE_NAME} ${UNIT_NAME} ${MODULE_DEPENDENCIES}) |
| 320 | + endif(MODULE_DEPENDENCIES) |
| 321 | + |
| 322 | + # Add it to the set of tests to run as part of "make test" |
| 323 | + add_test(${TEST_NAME} ${RUNNER_TARGET}) |
| 324 | + foreach(TGT ${INSTALL_TARGET_LIST}) |
| 325 | + install(TARGETS ${RUNNER_TARGET} DESTINATION ${TGT}/${UT_INSTALL_SUBDIR}) |
| 326 | + endforeach() |
| 327 | + |
| 328 | +endfunction(add_cfe_coverage_test) |
| 329 | + |
| 330 | + |
| 331 | +################################################################## |
| 332 | +# |
| 333 | +# FUNCTION: add_cfe_coverage_unit_include |
| 334 | +# |
| 335 | +# Add an "override" include directory for a specific unit test |
| 336 | +# |
| 337 | +# This can be used if a coverage test needs to override certain |
| 338 | +# C library header files only for a specific unit under test. The |
| 339 | +# include path is added only for the particular source files in the |
| 340 | +# specified coverage test unit. (Not for the coverage test itself). |
| 341 | +# |
| 342 | +# The executable target name follows the pattern: |
| 343 | +# "coverage-${MODULE_NAME}-${UNIT_NAME}-testrunner" |
| 344 | +# |
| 345 | +function(add_cfe_coverage_unit_include MODULE_NAME UNIT_NAME OVERRIDE_INCLUDE_DIRS) |
| 346 | + # For the object target only, the "override" includes should be injected |
| 347 | + # into the include path. Note it is important that this is only included |
| 348 | + # for the specific unit under test (object lib) not the coverage |
| 349 | + # test executable or test cases, since these typically need the real |
| 350 | + # version of these functions. |
| 351 | + target_include_directories(coverage-${MODULE_NAME}-${UNIT_NAME}-object PRIVATE |
| 352 | + ${OVERRIDE_INCLUDE_DIRS} ${ARGN} |
| 353 | + ) |
| 354 | + |
| 355 | +endfunction(add_cfe_coverage_unit_include) |
| 356 | + |
| 357 | + |
| 358 | +################################################################## |
| 359 | +# |
| 360 | +# FUNCTION: add_cfe_coverage_stubs |
| 361 | +# |
| 362 | +# Add stub library target for coverage testing. The stub library should |
| 363 | +# contain a stub implementation for every function defined in the public |
| 364 | +# API of the current module. |
| 365 | +# |
| 366 | +# NOTE: The first argument (MODULE_NAME) should match a name that was previously |
| 367 | +# passed to the add_cfe_app() function - as this references that previous |
| 368 | +# target to use the same compile definitions and include paths. |
| 369 | +# (however this does also allow extra stub libs to be created that are not |
| 370 | +# related to an existing module) |
| 371 | +# |
| 372 | +# The stub library target name follows the pattern: |
| 373 | +# "coverage-${MODULE_NAME}-stubs" |
| 374 | +# |
| 375 | +# The calling script may call target_link_libraries() (or other target functions) |
| 376 | +# to customize this target as needed. |
| 377 | +# |
| 378 | +# NOTE: To simplify linking and avoid possible problems there should ideally be a 1:1 |
| 379 | +# relationship between module source files and the stub files. Each stub file |
| 380 | +# should provide the same set of functions that the fsw source file provides. |
| 381 | +# (although its is not strictly required, it does help keep things more manageable). |
| 382 | +# |
| 383 | +function(add_cfe_coverage_stubs MODULE_NAME STUB_SRCS) |
| 384 | + |
| 385 | + set(STUB_TARGET "coverage-${MODULE_NAME}-stubs") |
| 386 | + |
| 387 | + add_library(${STUB_TARGET} STATIC |
| 388 | + ${STUB_SRCS} ${ARGN} |
| 389 | + ) |
| 390 | + |
| 391 | + # If the MODULE_NAME refers to an existing CFE APP/LIB target, then |
| 392 | + # use the same set of include dirs/definitions that is used from the app target |
| 393 | + # This is not required; "extra" stub libs may be created that are not |
| 394 | + # directly associated with an existing module. |
| 395 | + if (TARGET ${MODULE_NAME}) |
| 396 | + target_include_directories(${STUB_TARGET} PUBLIC |
| 397 | + $<TARGET_PROPERTY:${MODULE_NAME},INCLUDE_DIRECTORIES> |
| 398 | + ) |
| 399 | + target_compile_definitions(${STUB_TARGET} PUBLIC |
| 400 | + $<TARGET_PROPERTY:${MODULE_NAME},COMPILE_DEFINITIONS> |
| 401 | + ) |
212 | 402 | endif() |
213 | | - set(UTLFLAGS "${UTLFLAGS} -pg --coverage") |
214 | | - |
215 | | - set_target_properties(${UT_NAME} PROPERTIES LINK_FLAGS "${UTLFLAGS}" COMPILE_DEFINITIONS "${UTCDEFS}" COMPILE_FLAGS "${UTCFLAGS}") |
216 | | - target_link_libraries(${UT_NAME} utl_${UT_NAME}) |
217 | | - add_test(${UT_NAME} ${UT_NAME}) |
218 | | -endfunction(add_unit_test_exe) |
| 403 | + |
| 404 | + target_link_libraries(${STUB_TARGET} ut_assert) |
| 405 | + |
| 406 | +endfunction(add_cfe_coverage_stubs) |
219 | 407 |
|
220 | 408 |
|
221 | 409 | ################################################################## |
|
0 commit comments