1include(CompilerRTCompile)
2
3set(SANITIZER_UNITTESTS
4  sanitizer_allocator_test.cc
5  sanitizer_atomic_test.cc
6  sanitizer_bitvector_test.cc
7  sanitizer_bvgraph_test.cc
8  sanitizer_common_test.cc
9  sanitizer_deadlock_detector_test.cc
10  sanitizer_flags_test.cc
11  sanitizer_format_interceptor_test.cc
12  sanitizer_ioctl_test.cc
13  sanitizer_libc_test.cc
14  sanitizer_linux_test.cc
15  sanitizer_list_test.cc
16  sanitizer_mutex_test.cc
17  sanitizer_nolibc_test.cc
18  sanitizer_posix_test.cc
19  sanitizer_printf_test.cc
20  sanitizer_procmaps_test.cc
21  sanitizer_stackdepot_test.cc
22  sanitizer_stacktrace_test.cc
23  sanitizer_stoptheworld_test.cc
24  sanitizer_suppressions_test.cc
25  sanitizer_test_main.cc
26  sanitizer_thread_registry_test.cc)
27
28set(SANITIZER_TEST_HEADERS
29  sanitizer_pthread_wrappers.h
30  sanitizer_test_config.h
31  sanitizer_test_utils.h)
32foreach(header ${SANITIZER_HEADERS})
33  list(APPEND SANITIZER_TEST_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})
34endforeach()
35
36set(SANITIZER_TEST_CFLAGS_COMMON
37  ${COMPILER_RT_TEST_CFLAGS}
38  ${COMPILER_RT_GTEST_CFLAGS}
39  -I${COMPILER_RT_SOURCE_DIR}/include
40  -I${COMPILER_RT_SOURCE_DIR}/lib
41  -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common
42  -fno-rtti
43  -O2
44  -Werror=sign-compare
45  -Wno-non-virtual-dtor)
46
47# -gline-tables-only must be enough for these tests, so use it if possible.
48if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
49  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)
50else()
51  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)
52endif()
53
54if(NOT MSVC)
55  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON --driver-mode=g++)
56endif()
57
58append_if(COMPILER_RT_HAS_LIBDL -ldl SANITIZER_TEST_LINK_FLAGS_COMMON)
59append_if(COMPILER_RT_HAS_LIBPTHREAD -pthread SANITIZER_TEST_LINK_FLAGS_COMMON)
60# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. Also,
61# 'libm' shall be specified explicitly to build i386 tests.
62if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
63  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON "-lc++ -lm")
64endif()
65
66include_directories(..)
67include_directories(../..)
68
69# Adds static library which contains sanitizer_common object file
70# (universal binary on Mac and arch-specific object files on Linux).
71macro(add_sanitizer_common_lib library)
72  add_library(${library} STATIC ${ARGN})
73  set_target_properties(${library} PROPERTIES
74    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
75endmacro()
76
77function(get_sanitizer_common_lib_for_arch arch lib lib_name)
78  if(APPLE)
79    set(tgt_name "RTSanitizerCommon.test.osx")
80  else()
81    set(tgt_name "RTSanitizerCommon.test.${arch}")
82  endif()
83  set(${lib} "${tgt_name}" PARENT_SCOPE)
84  if(NOT MSVC)
85    set(${lib_name} "lib${tgt_name}.a" PARENT_SCOPE)
86  else()
87    set(${lib_name} "${tgt_name}.lib" PARENT_SCOPE)
88  endif()
89endfunction()
90
91# Sanitizer_common unit tests testsuite.
92add_custom_target(SanitizerUnitTests)
93set_target_properties(SanitizerUnitTests PROPERTIES
94  FOLDER "Sanitizer unittests")
95
96# Adds sanitizer tests for architecture.
97macro(add_sanitizer_tests_for_arch arch)
98  get_target_flags_for_arch(${arch} TARGET_FLAGS)
99  set(SANITIZER_TEST_SOURCES ${SANITIZER_UNITTESTS}
100                             ${COMPILER_RT_GTEST_SOURCE})
101  set(SANITIZER_TEST_COMPILE_DEPS ${SANITIZER_TEST_HEADERS})
102  if(NOT COMPILER_RT_STANDALONE_BUILD)
103    list(APPEND SANITIZER_TEST_COMPILE_DEPS gtest)
104  endif()
105  set(SANITIZER_TEST_OBJECTS)
106  foreach(source ${SANITIZER_TEST_SOURCES})
107    get_filename_component(basename ${source} NAME)
108    set(output_obj "${basename}.${arch}.o")
109    clang_compile(${output_obj} ${source}
110                  CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${TARGET_FLAGS}
111                  DEPS ${SANITIZER_TEST_COMPILE_DEPS})
112    list(APPEND SANITIZER_TEST_OBJECTS ${output_obj})
113  endforeach()
114  get_sanitizer_common_lib_for_arch(${arch} SANITIZER_COMMON_LIB
115                                    SANITIZER_COMMON_LIB_NAME)
116  # Add unittest target.
117  set(SANITIZER_TEST_NAME "Sanitizer-${arch}-Test")
118  add_compiler_rt_test(SanitizerUnitTests ${SANITIZER_TEST_NAME}
119                       OBJECTS ${SANITIZER_TEST_OBJECTS}
120                               ${SANITIZER_COMMON_LIB_NAME}
121                       DEPS ${SANITIZER_TEST_OBJECTS} ${SANITIZER_COMMON_LIB}
122                       LINK_FLAGS ${SANITIZER_TEST_LINK_FLAGS_COMMON}
123                                  ${TARGET_FLAGS})
124
125  if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND "${arch}" STREQUAL "x86_64")
126    # Test that the libc-independent part of sanitizer_common is indeed
127    # independent of libc, by linking this binary without libc (here) and
128    # executing it (unit test in sanitizer_nolibc_test.cc).
129    clang_compile(sanitizer_nolibc_test_main.${arch}.o
130                  sanitizer_nolibc_test_main.cc
131                  CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${TARGET_FLAGS}
132                  DEPS ${SANITIZER_TEST_COMPILE_DEPS})
133    add_compiler_rt_test(SanitizerUnitTests "Sanitizer-${arch}-Test-Nolibc"
134                         OBJECTS sanitizer_nolibc_test_main.${arch}.o
135                                 -Wl,-whole-archive
136                                 libRTSanitizerCommon.test.nolibc.${arch}.a
137                                 -Wl,-no-whole-archive
138                         DEPS sanitizer_nolibc_test_main.${arch}.o
139                              RTSanitizerCommon.test.nolibc.${arch}
140                         LINK_FLAGS -nostdlib ${TARGET_FLAGS})
141  endif()
142endmacro()
143
144if(COMPILER_RT_CAN_EXECUTE_TESTS)
145  # We use just-built clang to build sanitizer_common unittests, so we must
146  # be sure that produced binaries would work.
147  if(APPLE)
148    add_sanitizer_common_lib("RTSanitizerCommon.test.osx"
149                             $<TARGET_OBJECTS:RTSanitizerCommon.osx>)
150  else()
151    if(CAN_TARGET_x86_64)
152      add_sanitizer_common_lib("RTSanitizerCommon.test.x86_64"
153                               $<TARGET_OBJECTS:RTSanitizerCommon.x86_64>
154                               $<TARGET_OBJECTS:RTSanitizerCommonLibc.x86_64>)
155      add_sanitizer_common_lib("RTSanitizerCommon.test.nolibc.x86_64"
156                               $<TARGET_OBJECTS:RTSanitizerCommon.x86_64>)
157    endif()
158    if(CAN_TARGET_i386)
159      add_sanitizer_common_lib("RTSanitizerCommon.test.i386"
160                               $<TARGET_OBJECTS:RTSanitizerCommon.i386>
161                               $<TARGET_OBJECTS:RTSanitizerCommonLibc.i386>)
162    endif()
163  endif()
164  if(CAN_TARGET_x86_64)
165    add_sanitizer_tests_for_arch(x86_64)
166  endif()
167  if(CAN_TARGET_i386)
168    add_sanitizer_tests_for_arch(i386)
169  endif()
170endif()
171
172if(ANDROID)
173  # We assume that unit tests on Android are built in a build
174  # tree with fresh Clang as a host compiler.
175  add_executable(SanitizerTest
176    ${SANITIZER_UNITTESTS}
177    ${COMPILER_RT_GTEST_SOURCE}
178    $<TARGET_OBJECTS:RTSanitizerCommon.arm.android>)
179  set_target_compile_flags(SanitizerTest
180    ${SANITIZER_COMMON_CFLAGS}
181    ${SANITIZER_TEST_CFLAGS_COMMON})
182  # Setup correct output directory and link flags.
183  set_target_properties(SanitizerTest PROPERTIES
184    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
185  set_target_link_flags(SanitizerTest ${SANITIZER_TEST_LINK_FLAGS_COMMON})
186  target_link_libraries(SanitizerTest log)
187  # Add unit test to test suite.
188  add_dependencies(SanitizerUnitTests SanitizerTest)
189endif()
190