cmake_minimum_required(VERSION 3.13 FATAL_ERROR) cmake_policy(SET CMP0054 NEW) cmake_policy(SET CMP0057 NEW) project(threadx_smp_test LANGUAGES C) # Set build configurations set(BUILD_CONFIGURATIONS default_build_coverage disable_notify_callbacks_build stack_checking_build stack_checking_rand_fill_build trace_build misra_build misra_trace_build smp_debug_build) set(CMAKE_CONFIGURATION_TYPES ${BUILD_CONFIGURATIONS} CACHE STRING "list of supported configuration types" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES}) list(GET CMAKE_CONFIGURATION_TYPES 0 BUILD_TYPE) if((NOT CMAKE_BUILD_TYPE) OR (NOT ("${CMAKE_BUILD_TYPE}" IN_LIST CMAKE_CONFIGURATION_TYPES))) set(CMAKE_BUILD_TYPE "${BUILD_TYPE}" CACHE STRING "Build Type of the project" FORCE) endif() message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.") set(default_build_coverage "") set(disable_notify_callbacks_build -DTX_DISABLE_NOTIFY_CALLBACKS) set(stack_checking_build -DTX_ENABLE_STACK_CHECKING) set(stack_checking_rand_fill_build -DTX_ENABLE_STACK_CHECKING -DTX_ENABLE_RANDOM_NUMBER_STACK_FILLING) set(trace_build -DTX_ENABLE_EVENT_TRACE) # TX_MISRA_ENABLE routes every pointer conversion in the kernel through the # shim functions in common_smp/src/tx_misra.c. None of the configurations above # defines it, so that file's whole body is compiled out of all of them and the # shim -- certified source -- carries no coverage at all. It is also the source # the MISRA analysis is run against, so without this configuration the build # that is analysed and the build that is covered are different builds of the # same tree. set(misra_build -DTX_MISRA_ENABLE) # TX_MISRA_ENABLE and TX_ENABLE_EVENT_TRACE together reach a region of # common_smp/src/tx_misra.c that no other configuration compiles: the MISRA form # of the in-line trace insert and the five pointer conversions the trace sources # use. misra_build defines the first macro alone and trace_build the second # alone, so that region was absent from the coverage denominator rather than # uncovered in it -- the same reason misra_build itself exists. # # It needs TX_SOURCE_CODE as well, which is applied to the kernel target further # down rather than here -- see the comment there for why. set(misra_trace_build -DTX_MISRA_ENABLE -DTX_ENABLE_EVENT_TRACE) # TX_THREAD_SMP_DEBUG_ENABLE is the SMP tree's second whole-file macro. # common_smp/src/tx_thread_smp_debug_entry_insert.c sits entirely under it and # nothing defined it, so the file compiled to nothing in every configuration and # was absent from the coverage denominator rather than uncovered in it. Eight # further files carry regions behind the same macro, all of them top-level rather # than nested inside another guard, so this one configuration reaches every one # of them and no combination build is needed. set(smp_debug_build -DTX_THREAD_SMP_DEBUG_ENABLE) add_compile_options( -m32 -std=c99 -ggdb -g3 -gdwarf-2 -fdiagnostics-color # -Werror -DTX_THREAD_SMP_ONLY_CORE_0_DEFAULT -DTX_SMP_NOT_POSSIBLE -DTX_REGRESSION_TEST -DTEST_STACK_SIZE_PRINTF=4096 ${${CMAKE_BUILD_TYPE}}) add_link_options(-m32) enable_testing() add_subdirectory(threadx_smp) add_subdirectory(regression) add_subdirectory(samples) # Coverage # # The gate here used to be the build type alone, and only one of the five # configurations -- default_build_coverage -- has a name matching "*_coverage". # So four configurations built and ran every test and their coverage was thrown # away. That is not redundancy discarded: each configuration selects a different # set of TX_ feature macros, so the code the other four compile is *absent from # the denominator* rather than reported as uncovered. A figure taken from one of # them is the executable-line count of one configuration, not of the kernel. # # TX_COVERAGE instruments a build regardless of its name. It defaults to OFF and # the build-type match is kept, so configuring a single configuration by hand # behaves exactly as it did before; the regression run turns it on for all five # and merges the results. option(TX_COVERAGE "Instrument this build for coverage regardless of build type" OFF) if(TX_COVERAGE OR CMAKE_BUILD_TYPE MATCHES ".*_coverage") target_compile_options(threadx_smp PRIVATE -fprofile-arcs -ftest-coverage) target_link_options(threadx_smp PRIVATE -fprofile-arcs -ftest-coverage) endif() # tx_misra.c is the only one of the 194 files in common_smp/src that does not # define TX_SOURCE_CODE for itself, and the prototypes for the five trace # conversions it defines sit behind that macro in tx_trace.h. Without it the file # defines five functions with no previous declaration. This tree does not build # with -Werror, so that is a warning here rather than the hard failure it is in # the monoprocessor tree -- which makes it easier to miss and no less wrong: the # coverage evidence would come from a translation unit where five certified # functions have no visible prototype. # # The empty value matches the plain "#define TX_SOURCE_CODE" the other 193 files # carry, which is why adding it changes no object code in any configuration. # # It goes on the kernel target rather than in add_compile_options above, because # TX_SOURCE_CODE is what tells tx_api.h it is compiling ThreadX rather than an # application: it suppresses the public tx_* API mappings, which the tests and the # sample need. Applied globally it takes the API away from every caller. # # The defect itself is in the header and is reported upstream. This keeps our # build independent of when it is fixed. if(CMAKE_BUILD_TYPE STREQUAL "misra_trace_build") target_compile_definitions(threadx_smp PRIVATE TX_SOURCE_CODE=) endif() target_compile_options( threadx_smp PRIVATE # -Werror -Wall -Wextra -pedantic -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wunused -Wuninitialized -Wmissing-declarations -Wconversion -Wpointer-arith # -Wshadow -Wlogical-op -Waggregate-return -Wfloat-equal)