CMakeLists.txt revision d7d7b5f39cf5bbc36403afb0a94d473519c7ab78
1# Testing rules for AddressSanitizer.
2#
3# These are broken into two buckets. One set of tests directly interacts with
4# the runtime library and checks its functionality. These are the
5# no-instrumentation tests.
6#
7# Another group of tests relies upon the ability to compile the test with
8# address sanitizer instrumentation pass. These tests form "integration" tests
9# and have some elements of version skew -- they test the *host* compiler's
10# instrumentation against the just-built runtime library.
11
12include(CheckCXXCompilerFlag)
13include(CompilerRTCompile)
14include(CompilerRTUnittests)
15
16include_directories(..)
17include_directories(../..)
18
19set(ASAN_UNITTEST_HEADERS
20  asan_mac_test.h
21  asan_test_config.h
22  asan_test_utils.h)
23
24set(ASAN_UNITTEST_COMMON_CFLAGS
25  ${COMPILER_RT_GTEST_INCLUDE_CFLAGS}
26  -I${COMPILER_RT_SOURCE_DIR}/include
27  -I${COMPILER_RT_SOURCE_DIR}/lib
28  -I${COMPILER_RT_SOURCE_DIR}/lib/asan
29  -Wall
30  -Wno-format
31  -Werror
32  -g
33  -O2
34)
35
36if(SUPPORTS_NO_VARIADIC_MACROS_FLAG)
37  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -Wno-variadic-macros)
38endif()
39
40# Use -D instead of definitions to please custom compile command.
41if(ANDROID)
42  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
43    -DASAN_LOW_MEMORY=1
44    -DASAN_HAS_BLACKLIST=1
45    -DASAN_HAS_EXCEPTIONS=1
46    -DASAN_NEEDS_SEGV=0
47    -DASAN_UAR=0
48    -fPIE
49  )
50else()
51  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
52    -DASAN_HAS_BLACKLIST=1
53    -DASAN_HAS_EXCEPTIONS=1
54    -DASAN_NEEDS_SEGV=1
55    -DASAN_UAR=0
56  )
57endif()
58
59set(ASAN_LINK_FLAGS)
60if(ANDROID)
61  # On Android, we link with ASan runtime manually
62  list(APPEND ASAN_LINK_FLAGS -pie)
63else()
64  # On other platforms, we depend on Clang driver behavior,
65  # passing -fsanitize=address flag.
66  list(APPEND ASAN_LINK_FLAGS -fsanitize=address)
67endif()
68# Unit tests on Mac depend on Foundation.
69if(APPLE)
70  list(APPEND ASAN_LINK_FLAGS -framework Foundation)
71endif()
72# Unit tests require libstdc++.
73list(APPEND ASAN_LINK_FLAGS -lstdc++)
74
75set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
76
77set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
78  ${ASAN_UNITTEST_COMMON_CFLAGS}
79  -fsanitize=address
80  -mllvm "-asan-blacklist=${ASAN_BLACKLIST_FILE}"
81  -mllvm -asan-stack=1
82  -mllvm -asan-globals=1
83  -mllvm -asan-mapping-scale=0        # default will be used
84  -mllvm -asan-mapping-offset-log=-1  # default will be used
85  -mllvm -asan-use-after-return=0
86)
87
88# Compile source for the given architecture, using compiler
89# options in ${ARGN}, and add it to the object list.
90macro(asan_compile obj_list source arch)
91  get_filename_component(basename ${source} NAME)
92  set(output_obj "${basename}.${arch}.o")
93  get_target_flags_for_arch(${arch} TARGET_CFLAGS)
94  clang_compile(${output_obj} ${source}
95                CFLAGS ${ARGN} ${TARGET_CFLAGS}
96                DEPS gtest ${ASAN_RUNTIME_LIBRARIES}
97                           ${ASAN_UNITTEST_HEADERS}
98                           ${ASAN_BLACKLIST_FILE})
99  list(APPEND ${obj_list} ${output_obj})
100endmacro()
101
102# Link ASan unit test for a given architecture from a set
103# of objects in ${ARGN}.
104macro(add_asan_test test_suite test_name arch)
105  get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
106  add_compiler_rt_test(${test_suite} ${test_name}
107                       OBJECTS ${ARGN}
108                       DEPS ${ASAN_RUNTIME_LIBRARIES} ${ARGN}
109                       LINK_FLAGS ${ASAN_LINK_FLAGS}
110                                  ${TARGET_LINK_FLAGS})
111endmacro()
112
113# Main AddressSanitizer unit tests.
114add_custom_target(AsanUnitTests)
115set_target_properties(AsanUnitTests PROPERTIES FOLDER "ASan unit tests")
116# ASan benchmarks (not actively used now).
117add_custom_target(AsanBenchmarks)
118set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Asan benchmarks")
119
120# Adds ASan unit tests and benchmarks for architecture.
121macro(add_asan_tests_for_arch arch)
122  # Build gtest instrumented with ASan.
123  set(ASAN_INST_GTEST)
124  asan_compile(ASAN_INST_GTEST ${COMPILER_RT_GTEST_SOURCE} ${arch} 
125                               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
126  # Instrumented tests.
127  set(ASAN_INST_TEST_OBJECTS)
128  asan_compile(ASAN_INST_TEST_OBJECTS asan_globals_test.cc ${arch}
129               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
130  asan_compile(ASAN_INST_TEST_OBJECTS asan_test.cc ${arch}
131               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
132  if (APPLE)
133    asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test.mm ${arch}
134                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC)
135  endif()
136  # Uninstrumented tests.
137  set(ASAN_NOINST_TEST_OBJECTS)
138  asan_compile(ASAN_NOINST_TEST_OBJECTS asan_noinst_test.cc ${arch}
139               ${ASAN_UNITTEST_COMMON_CFLAGS})
140  asan_compile(ASAN_NOINST_TEST_OBJECTS asan_test_main.cc ${arch}
141               ${ASAN_UNITTEST_COMMON_CFLAGS})
142  # Link everything together.
143  add_asan_test(AsanUnitTests "Asan-${arch}-Test" ${arch}
144                ${ASAN_NOINST_TEST_OBJECTS}
145                ${ASAN_INST_TEST_OBJECTS} ${ASAN_INST_GTEST})
146
147  # Instrumented benchmarks.
148  set(ASAN_BENCHMARKS_OBJECTS)
149  asan_compile(ASAN_BENCHMARKS_OBJECTS asan_benchmarks_test.cc ${arch}
150               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
151  # Link benchmarks.
152  add_asan_test(AsanBenchmarks "Asan-${arch}-Benchmark" ${arch}
153                ${ASAN_BENCHMARKS_OBJECTS} ${ASAN_INST_GTEST})
154endmacro()
155
156if(COMPILER_RT_CAN_EXECUTE_TESTS)
157  if(CAN_TARGET_X86_64)
158    add_asan_tests_for_arch(x86_64)
159  endif()
160  if(CAN_TARGET_I386)
161    add_asan_tests_for_arch(i386)
162  endif()
163endif()
164
165if(ANDROID)
166  # We assume that unit tests on Android are built in a build
167  # tree with fresh Clang as a host compiler.
168  set(ASAN_NOINST_TEST_SOURCES asan_noinst_test.cc asan_test_main.cc)
169  set(ASAN_INST_TEST_SOURCES asan_globals_test.cc asan_test.cc)
170  add_library(asan_noinst_test OBJECT ${ASAN_NOINST_TEST_SOURCES})
171  set_target_compile_flags(asan_noinst_test ${ASAN_UNITTEST_COMMON_CFLAGS})
172  add_library(asan_inst_test OBJECT
173              ${ASAN_INST_TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE})  
174  set_target_compile_flags(asan_inst_test ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
175  add_executable(AsanTest
176    $<TARGET_OBJECTS:asan_noinst_test>
177    $<TARGET_OBJECTS:asan_inst_test>
178  )
179  # Setup correct output directory and link flags.
180  get_unittest_directory(OUTPUT_DIR)
181  set_target_properties(AsanTest PROPERTIES
182    RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR})
183  set_target_link_flags(AsanTest ${ASAN_LINK_FLAGS})
184  target_link_libraries(AsanTest clang_rt.asan-arm-android)
185  # Add unit test to test suite.
186  add_dependencies(AsanUnitTests AsanTest)
187endif()
188