Files
PX4-Autopilot/cmake/px4_add_gtest.cmake
Julian Oes 344c5c356e fix(build): disable fuzztest when building with TSAN
fuzztest's coverage instrumentation is incompatible with Thread
Sanitizer. Add px4_setup_gtest_without_fuzztest() macro to
cmake/px4_add_gtest.cmake that fetches GTest standalone and stubs out
fuzztest cmake functions. Guard all fuzztest-specific code on
TARGET fuzztest::fuzztest so it compiles cleanly without fuzztest.
2026-07-02 08:42:49 -07:00

179 lines
6.4 KiB
CMake

############################################################################
#
# Copyright (c) 2019 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
# Attach only matching test binaries to `test_results` when TESTFILTER is set.
# `ctest -R` filters execution only; without this helper the build still
# compiles every gtest target before running the filtered subset.
function(add_filtered_test_dependencies TESTNAME)
if(NOT TESTFILTER OR "${TESTNAME}" MATCHES "${TESTFILTER}")
add_dependencies(test_results ${TESTNAME})
endif()
endfunction()
#=============================================================================
#
# px4_setup_gtest_without_fuzztest
#
# Fetches GTest standalone and stubs out fuzztest cmake functions.
# Used when fuzztest is not available (e.g. TSAN builds where fuzztest's
# coverage instrumentation is incompatible).
#
macro(px4_setup_gtest_without_fuzztest)
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.16.0
)
FetchContent_MakeAvailable(googletest)
function(link_fuzztest name)
target_link_libraries(${name} PRIVATE gtest gtest_main)
endfunction()
macro(fuzztest_setup_fuzzing_flags)
endmacro()
endmacro()
#=============================================================================
#
# px4_add_unit_gtest
#
# Adds a googletest unit test to the test_results target.
#
function(px4_add_unit_gtest)
# skip if unit testing is not configured
if(BUILD_TESTING)
# parse source file and library dependencies from arguments
px4_parse_function_args(
NAME px4_add_unit_gtest
ONE_VALUE SRC
MULTI_VALUE EXTRA_SRCS COMPILE_FLAGS INCLUDES LINKLIBS
REQUIRED SRC
ARGN ${ARGN})
# infer test name from source filname
get_filename_component(TESTNAME ${SRC} NAME_WE)
string(REPLACE Test "" TESTNAME ${TESTNAME})
set(TESTNAME unit-${TESTNAME})
# build a binary for the unit test
add_executable(${TESTNAME} EXCLUDE_FROM_ALL ${SRC} ${EXTRA_SRCS})
# link the libary to test and gtest
target_link_libraries(${TESTNAME} PRIVATE ${LINKLIBS})
if(COMPILE_FLAGS)
target_compile_options(${TESTNAME} PRIVATE ${COMPILE_FLAGS})
endif()
if(INCLUDES)
target_include_directories(${TESTNAME} PRIVATE ${INCLUDES})
endif()
link_fuzztest(${TESTNAME})
# add the test to the ctest plan
add_test(NAME ${TESTNAME}
COMMAND ${TESTNAME}
WORKING_DIRECTORY ${PX4_BINARY_DIR})
# attach it to the unit test target
add_filtered_test_dependencies(${TESTNAME})
endif()
endfunction()
function(px4_add_functional_gtest)
# skip if unit testing is not configured
if(BUILD_TESTING)
# parse source file and library dependencies from arguments
px4_parse_function_args(
NAME px4_add_functional_gtest
ONE_VALUE SRC
MULTI_VALUE EXTRA_SRCS COMPILE_FLAGS INCLUDES LINKLIBS
REQUIRED SRC
ARGN ${ARGN})
# infer test name from source filname
get_filename_component(TESTNAME ${SRC} NAME_WE)
string(REPLACE Test "" TESTNAME ${TESTNAME})
set(TESTNAME functional-${TESTNAME})
# build a binary for the unit test
add_executable(${TESTNAME} EXCLUDE_FROM_ALL ${SRC} ${EXTRA_SRCS})
# link the libary to test and gtest
set(_FUNCTIONAL_GTEST_LIBS ${LINKLIBS} gtest_functional_main
px4_layer
px4_platform
uORB
systemlib
cdev
px4_work_queue
px4_daemon
work_queue
parameters
events
perf
tinybson
uorb_msgs)
if(TARGET fuzztest::fuzztest)
list(APPEND _FUNCTIONAL_GTEST_LIBS fuzztest::fuzztest) # Do not use link_fuzztest() here because that
# also links to fuzztest_gtest_main
else()
list(APPEND _FUNCTIONAL_GTEST_LIBS gtest)
endif()
# whole-archive so the daemon app-map stubs link even for small
# test libs, where link order would otherwise drop them
list(APPEND _FUNCTIONAL_GTEST_LIBS -Wl,--whole-archive test_stubs -Wl,--no-whole-archive)
target_link_libraries(${TESTNAME} PRIVATE ${_FUNCTIONAL_GTEST_LIBS})
target_compile_definitions(${TESTNAME} PRIVATE MODULE_NAME="${TESTNAME}")
if(COMPILE_FLAGS)
target_compile_options(${TESTNAME} PRIVATE ${COMPILE_FLAGS})
endif()
if(INCLUDES)
target_include_directories(${TESTNAME} PRIVATE ${INCLUDES})
endif()
# add the test to the ctest plan
add_test(NAME ${TESTNAME}
# functional tests need to run in a new process for each test,
# since they set up and tear down system components
COMMAND ${PX4_BINARY_DIR}/${TESTNAME})
# attach it to the unit test target
add_filtered_test_dependencies(${TESTNAME})
endif()
endfunction()