CMakeLists.txt revision 8925b71d67f03065e1c3871c4474e91bcb88f999
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_COMMON_CFLAGS
20  ${COMPILER_RT_GTEST_INCLUDE_CFLAGS}
21  -I${COMPILER_RT_SOURCE_DIR}/include
22  -I${COMPILER_RT_SOURCE_DIR}/lib
23  -I${COMPILER_RT_SOURCE_DIR}/lib/asan
24  -Wall
25  -Wno-format
26  -Werror
27  -g
28  -O2
29)
30
31if(SUPPORTS_NO_VARIADIC_MACROS_FLAG)
32  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -Wno-variadic-macros)
33endif()
34
35# Use -D instead of definitions to please custom compile command.
36if(ANDROID)
37  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
38    -DASAN_LOW_MEMORY=1
39    -DASAN_HAS_BLACKLIST=1
40    -DASAN_HAS_EXCEPTIONS=1
41    -DASAN_NEEDS_SEGV=0
42    -DASAN_UAR=0
43    -fPIE
44  )
45else()
46  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
47    -DASAN_HAS_BLACKLIST=1
48    -DASAN_HAS_EXCEPTIONS=1
49    -DASAN_NEEDS_SEGV=1
50    -DASAN_UAR=0
51  )
52endif()
53
54set(ASAN_LINK_FLAGS -fsanitize=address)
55if(ANDROID)
56  list(APPEND ASAN_LINK_FLAGS -pie)
57elseif(APPLE)
58  # Unit tests on Mac depend on Foundation.
59  list(APPEND ASAN_LINK_FLAGS -framework Foundation)
60endif()
61# Unit tests require libstdc++.
62list(APPEND ASAN_LINK_FLAGS -lstdc++)
63
64# Support 64-bit and 32-bit builds.
65if(LLVM_BUILD_32_BITS)
66  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -m32)
67  list(APPEND ASAN_LINK_FLAGS -m32)
68else()
69  list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -m64)
70  list(APPEND ASAN_LINK_FLAGS -m64)
71endif()
72
73set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
74
75set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
76  ${ASAN_UNITTEST_COMMON_CFLAGS}
77  -fsanitize=address
78  -mllvm "-asan-blacklist=${ASAN_BLACKLIST_FILE}"
79  -mllvm -asan-stack=1
80  -mllvm -asan-globals=1
81  -mllvm -asan-mapping-scale=0        # default will be used
82  -mllvm -asan-mapping-offset-log=-1  # default will be used
83  -mllvm -asan-use-after-return=0
84)
85
86# Compile source and add it to the object list using compiler
87# options in ${ARGN}.
88macro(asan_compile obj_list source)
89  get_filename_component(basename ${source} NAME)
90  set(output_obj "${basename}.o")
91  clang_compile(${output_obj} ${source}
92                CFLAGS ${ARGN}
93                DEPS gtest ${ASAN_RUNTIME_LIBRARIES}
94                           ${ASAN_BLACKLIST_FILE})
95  list(APPEND ${obj_list} ${output_obj})
96endmacro()
97
98# Link ASan unit test from a set of objects in ${ARGN}.
99macro(add_asan_test test_suite test_name)
100  message(STATUS "Link flags: ${ASAN_LINK_FLAGS}")
101  add_compiler_rt_test(${test_suite} ${test_name}
102                       OBJECTS ${ARGN}
103                       DEPS ${ASAN_RUNTIME_LIBRARIES}
104                       LINK_FLAGS ${ASAN_LINK_FLAGS})
105endmacro()
106
107# Main AddressSanitizer unit tests.
108add_custom_target(AsanUnitTests)
109set_target_properties(AsanUnitTests PROPERTIES FOLDER "ASan unit tests")
110# ASan benchmarks (not actively used now).
111add_custom_target(AsanBenchmarks)
112set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Asan benchmarks")
113
114# We only support building instrumented tests when we're not cross compiling
115# and targeting a unix-like system where we can predict viable compilation and
116# linking strategies.
117# We use a different approach to build these tests for Android. See below.
118if("${CMAKE_HOST_SYSTEM}" STREQUAL "${CMAKE_SYSTEM}" AND UNIX AND NOT ANDROID)
119  # Build gtest instrumented with ASan.
120  set(ASAN_INST_GTEST)
121  asan_compile(ASAN_INST_GTEST ${COMPILER_RT_GTEST_SOURCE}  
122               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
123  # Instrumented tests.
124  set(ASAN_INST_TEST_OBJECTS)
125  asan_compile(ASAN_INST_TEST_OBJECTS asan_globals_test.cc
126               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
127  asan_compile(ASAN_INST_TEST_OBJECTS asan_test.cc
128               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
129  if (APPLE)
130    asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test.mm
131                 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC)
132  endif()
133  # Uninstrumented tests.
134  set(ASAN_NOINST_TEST_OBJECTS)
135  asan_compile(ASAN_NOINST_TEST_OBJECTS asan_noinst_test.cc
136               ${ASAN_UNITTEST_COMMON_CFLAGS})
137  asan_compile(ASAN_NOINST_TEST_OBJECTS asan_test_main.cc
138               ${ASAN_UNITTEST_COMMON_CFLAGS})
139
140  # Link everything together.
141  add_asan_test(AsanUnitTests AsanTest ${ASAN_NOINST_TEST_OBJECTS}
142                ${ASAN_INST_TEST_OBJECTS} ${ASAN_INST_GTEST})
143
144  # Instrumented benchmarks.
145  set(ASAN_BENCHMARKS_OBJECTS)
146  asan_compile(ASAN_BENCHMARKS_OBJECTS asan_benchmarks_test.cc
147               ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
148  # Link benchmarks.
149  add_asan_test(AsanBenchmarks AsanBenchmark ${ASAN_BENCHMARKS_OBJECTS}
150                ${ASAN_INST_GTEST})
151endif()
152
153if(ANDROID)
154  # We assume that unit tests on Android are built in a build
155  # tree with fresh Clang as a host compiler.
156  set(ASAN_NOINST_TEST_SOURCES asan_noinst_test.cc asan_test_main.cc)
157  set(ASAN_INST_TEST_SOURCES asan_globals_test.cc asan_test.cc)
158  add_library(asan_noinst_test OBJECT ${ASAN_NOINST_TEST_SOURCES})
159  set_target_compile_flags(asan_noinst_test ${ASAN_UNITTEST_COMMON_CFLAGS})
160  add_library(asan_inst_test OBJECT
161              ${ASAN_INST_TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE})  
162  set_target_compile_flags(asan_inst_test ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
163  add_executable(AsanTest
164    $<TARGET_OBJECTS:asan_noinst_test>
165    $<TARGET_OBJECTS:asan_inst_test>
166  )
167  # Setup correct output directory and link flags.
168  get_unittest_directory(OUTPUT_DIR)
169  set_target_properties(AsanTest PROPERTIES
170    RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR})
171  set_target_link_flags(AsanTest ${ASAN_LINK_FLAGS})
172  add_dependencies(AsanTest ${ASAN_RUNTIME_LIBRARIES})
173  # Add unit test to test suite.
174  add_dependencies(AsanUnitTests AsanTest)
175endif()
176