summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/tests/CMakeLists.txt
blob: 5b48b6b613e72247243b9e1fd330f9c5a0e8a7f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
include(CompilerRTCompile)

set(SANITIZER_UNITTESTS
  sanitizer_allocator_test.cc
  sanitizer_atomic_test.cc
  sanitizer_common_test.cc
  sanitizer_flags_test.cc
  sanitizer_format_interceptor_test.cc
  sanitizer_ioctl_test.cc
  sanitizer_libc_test.cc
  sanitizer_linux_test.cc
  sanitizer_list_test.cc
  sanitizer_mutex_test.cc
  sanitizer_nolibc_test.cc
  sanitizer_posix_test.cc
  sanitizer_printf_test.cc
  sanitizer_procmaps_test.cc
  sanitizer_stackdepot_test.cc
  sanitizer_stacktrace_test.cc
  sanitizer_stoptheworld_test.cc
  sanitizer_suppressions_test.cc
  sanitizer_test_main.cc
  sanitizer_thread_registry_test.cc)

set(SANITIZER_TEST_HEADERS
  sanitizer_test_utils.h)
foreach(header ${SANITIZER_HEADERS})
  list(APPEND SANITIZER_TEST_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})
endforeach()

set(SANITIZER_TEST_CFLAGS_COMMON
  ${COMPILER_RT_GTEST_INCLUDE_CFLAGS}
  -I${COMPILER_RT_SOURCE_DIR}/include
  -I${COMPILER_RT_SOURCE_DIR}/lib
  -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common
  -DGTEST_HAS_RTTI=0
  -O2 -g -fno-rtti
  -Wall -Werror -Werror=sign-compare)

set(SANITIZER_TEST_LINK_FLAGS_COMMON
  -lstdc++ -ldl)

include_directories(..)
include_directories(../..)

# Adds static library which contains sanitizer_common object file
# (universal binary on Mac and arch-specific object files on Linux).
macro(add_sanitizer_common_lib library)
  add_library(${library} STATIC ${ARGN})
  set_target_properties(${library} PROPERTIES
    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endmacro()

function(get_sanitizer_common_lib_for_arch arch lib lib_name)
  if(APPLE)
    set(tgt_name "RTSanitizerCommon.test.osx")
  else()
    set(tgt_name "RTSanitizerCommon.test.${arch}")
  endif()
  set(${lib} "${tgt_name}" PARENT_SCOPE)
  set(${lib_name} "lib${tgt_name}.a" PARENT_SCOPE)
endfunction()

# Sanitizer_common unit tests testsuite.
add_custom_target(SanitizerUnitTests)
set_target_properties(SanitizerUnitTests PROPERTIES
  FOLDER "Sanitizer unittests")

# Adds sanitizer tests for architecture.
macro(add_sanitizer_tests_for_arch arch)
  get_target_flags_for_arch(${arch} TARGET_FLAGS)
  set(SANITIZER_TEST_SOURCES ${SANITIZER_UNITTESTS}
                             ${COMPILER_RT_GTEST_SOURCE})
  set(SANITIZER_TEST_OBJECTS)
  foreach(source ${SANITIZER_TEST_SOURCES})
    get_filename_component(basename ${source} NAME)
    set(output_obj "${basename}.${arch}.o")
    clang_compile(${output_obj} ${source}
                  CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${TARGET_FLAGS}
                  DEPS gtest ${SANITIZER_RUNTIME_LIBRARIES}
                       ${SANITIZER_TEST_HEADERS})
    list(APPEND SANITIZER_TEST_OBJECTS ${output_obj})
  endforeach()
  get_sanitizer_common_lib_for_arch(${arch} SANITIZER_COMMON_LIB
                                    SANITIZER_COMMON_LIB_NAME)
  # Add unittest target.
  set(SANITIZER_TEST_NAME "Sanitizer-${arch}-Test")
  add_compiler_rt_test(SanitizerUnitTests ${SANITIZER_TEST_NAME}
                       OBJECTS ${SANITIZER_TEST_OBJECTS}
                               ${SANITIZER_COMMON_LIB_NAME}
                       DEPS ${SANITIZER_TEST_OBJECTS} ${SANITIZER_COMMON_LIB}
                       LINK_FLAGS ${SANITIZER_TEST_LINK_FLAGS_COMMON}
                                  -lpthread ${TARGET_FLAGS})

  if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND "${arch}" STREQUAL "x86_64")
    # Test that the libc-independent part of sanitizer_common is indeed
    # independent of libc, by linking this binary without libc (here) and
    # executing it (unit test in sanitizer_nolibc_test.cc).
    clang_compile(sanitizer_nolibc_test_main.${arch}.o
                  sanitizer_nolibc_test_main.cc
                  CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${TARGET_FLAGS}
                  DEPS ${SANITIZER_RUNTIME_LIBRARIES} ${SANITIZER_TEST_HEADERS})
    add_compiler_rt_test(SanitizerUnitTests "Sanitizer-${arch}-Test-Nolibc"
                         OBJECTS sanitizer_nolibc_test_main.${arch}.o
                                 -Wl,-whole-archive
                                 libRTSanitizerCommon.test.nolibc.${arch}.a
                                 -Wl,-no-whole-archive
                         DEPS sanitizer_nolibc_test_main.${arch}.o
                              RTSanitizerCommon.test.nolibc.${arch}
                         LINK_FLAGS -nostdlib ${TARGET_FLAGS})
  endif()
endmacro()

if(COMPILER_RT_CAN_EXECUTE_TESTS)
  # We use just-built clang to build sanitizer_common unittests, so we must
  # be sure that produced binaries would work.
  if(APPLE)
    add_sanitizer_common_lib("RTSanitizerCommon.test.osx"
                             $<TARGET_OBJECTS:RTSanitizerCommon.osx>)
  else()
    if(CAN_TARGET_x86_64)
      add_sanitizer_common_lib("RTSanitizerCommon.test.x86_64"
                               $<TARGET_OBJECTS:RTSanitizerCommon.x86_64>
                               $<TARGET_OBJECTS:RTSanitizerCommonLibc.x86_64>)
      add_sanitizer_common_lib("RTSanitizerCommon.test.nolibc.x86_64"
                               $<TARGET_OBJECTS:RTSanitizerCommon.x86_64>)
    endif()
    if(CAN_TARGET_i386)
      add_sanitizer_common_lib("RTSanitizerCommon.test.i386"
                               $<TARGET_OBJECTS:RTSanitizerCommon.i386>
                               $<TARGET_OBJECTS:RTSanitizerCommonLibc.i386>)
    endif()
  endif()
  if(CAN_TARGET_x86_64)
    add_sanitizer_tests_for_arch(x86_64)
  endif()
  if(CAN_TARGET_i386)
    add_sanitizer_tests_for_arch(i386)
  endif()

  # Run unittests as a part of lit testsuite.
  configure_lit_site_cfg(
    ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
    ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
    )

  add_lit_testsuite(check-sanitizer "Running sanitizer library unittests"
    ${CMAKE_CURRENT_BINARY_DIR}
    DEPENDS SanitizerUnitTests
    )
  set_target_properties(check-sanitizer PROPERTIES FOLDER "Sanitizer unittests")
endif()

if(ANDROID)
  # We assume that unit tests on Android are built in a build
  # tree with fresh Clang as a host compiler.
  add_executable(SanitizerTest
    ${SANITIZER_UNITTESTS}
    ${COMPILER_RT_GTEST_SOURCE}
    $<TARGET_OBJECTS:RTSanitizerCommon.arm.android>)
  set_target_compile_flags(SanitizerTest
    ${SANITIZER_COMMON_CFLAGS}
    ${SANITIZER_TEST_CFLAGS_COMMON})
  # Setup correct output directory and link flags.
  set_target_properties(SanitizerTest PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  set_target_link_flags(SanitizerTest ${SANITIZER_TEST_LINK_FLAGS_COMMON})
  # Add unit test to test suite.
  add_dependencies(SanitizerUnitTests SanitizerTest)
endif()