CMakeLists.txt revision 2f66ab25cbb000289b79bca042b4136d92331b44
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) 55if(ANDROID) 56 # On Android, we link with ASan runtime manually 57 list(APPEND ASAN_LINK_FLAGS -pie) 58else() 59 # On other platforms, we depend on Clang driver behavior, 60 # passing -fsanitize=address flag. 61 list(APPEND ASAN_LINK_FLAGS -fsanitize=address) 62endif() 63# Unit tests on Mac depend on Foundation. 64if(APPLE) 65 list(APPEND ASAN_LINK_FLAGS -framework Foundation) 66endif() 67# Unit tests require libstdc++. 68list(APPEND ASAN_LINK_FLAGS -lstdc++) 69 70set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore") 71 72set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS 73 ${ASAN_UNITTEST_COMMON_CFLAGS} 74 -fsanitize=address 75 -mllvm "-asan-blacklist=${ASAN_BLACKLIST_FILE}" 76 -mllvm -asan-stack=1 77 -mllvm -asan-globals=1 78 -mllvm -asan-mapping-scale=0 # default will be used 79 -mllvm -asan-mapping-offset-log=-1 # default will be used 80 -mllvm -asan-use-after-return=0 81) 82 83# Compile source for the given architecture, using compiler 84# options in ${ARGN}, and add it to the object list. 85macro(asan_compile obj_list source arch) 86 get_filename_component(basename ${source} NAME) 87 set(output_obj "${basename}.${arch}.o") 88 get_target_flags_for_arch(${arch} TARGET_CFLAGS) 89 clang_compile(${output_obj} ${source} 90 CFLAGS ${ARGN} ${TARGET_CFLAGS} 91 DEPS gtest ${ASAN_RUNTIME_LIBRARIES} 92 ${ASAN_BLACKLIST_FILE}) 93 list(APPEND ${obj_list} ${output_obj}) 94endmacro() 95 96# Link ASan unit test for a given architecture from a set 97# of objects in ${ARGN}. 98macro(add_asan_test test_suite test_name arch) 99 get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) 100 add_compiler_rt_test(${test_suite} ${test_name} 101 OBJECTS ${ARGN} 102 DEPS ${ASAN_RUNTIME_LIBRARIES} 103 LINK_FLAGS ${ASAN_LINK_FLAGS} 104 ${TARGET_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# Adds ASan unit tests and benchmarks for architecture. 115macro(add_asan_tests_for_arch arch) 116 # Build gtest instrumented with ASan. 117 set(ASAN_INST_GTEST) 118 asan_compile(ASAN_INST_GTEST ${COMPILER_RT_GTEST_SOURCE} ${arch} 119 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) 120 # Instrumented tests. 121 set(ASAN_INST_TEST_OBJECTS) 122 asan_compile(ASAN_INST_TEST_OBJECTS asan_globals_test.cc ${arch} 123 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) 124 asan_compile(ASAN_INST_TEST_OBJECTS asan_test.cc ${arch} 125 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) 126 if (APPLE) 127 asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test.mm ${arch} 128 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC) 129 endif() 130 # Uninstrumented tests. 131 set(ASAN_NOINST_TEST_OBJECTS) 132 asan_compile(ASAN_NOINST_TEST_OBJECTS asan_noinst_test.cc ${arch} 133 ${ASAN_UNITTEST_COMMON_CFLAGS}) 134 asan_compile(ASAN_NOINST_TEST_OBJECTS asan_test_main.cc ${arch} 135 ${ASAN_UNITTEST_COMMON_CFLAGS}) 136 # Link everything together. 137 add_asan_test(AsanUnitTests "Asan-${arch}-Test" ${arch} 138 ${ASAN_NOINST_TEST_OBJECTS} 139 ${ASAN_INST_TEST_OBJECTS} ${ASAN_INST_GTEST}) 140 141 # Instrumented benchmarks. 142 set(ASAN_BENCHMARKS_OBJECTS) 143 asan_compile(ASAN_BENCHMARKS_OBJECTS asan_benchmarks_test.cc ${arch} 144 ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) 145 # Link benchmarks. 146 add_asan_test(AsanBenchmarks "Asan-${arch}-Benchmark" ${arch} 147 ${ASAN_BENCHMARKS_OBJECTS} ${ASAN_INST_GTEST}) 148endmacro() 149 150# We only support building instrumented tests when we're not cross compiling 151# and targeting a unix-like system where we can predict viable compilation and 152# linking strategies. 153# We use a different approach to build these tests for Android. See below. 154if("${CMAKE_HOST_SYSTEM}" STREQUAL "${CMAKE_SYSTEM}" AND UNIX AND NOT ANDROID) 155 if(CAN_TARGET_X86_64) 156 add_asan_tests_for_arch(x86_64) 157 endif() 158 if(CAN_TARGET_I386) 159 add_asan_tests_for_arch(i386) 160 endif() 161endif() 162 163if(ANDROID) 164 # We assume that unit tests on Android are built in a build 165 # tree with fresh Clang as a host compiler. 166 set(ASAN_NOINST_TEST_SOURCES asan_noinst_test.cc asan_test_main.cc) 167 set(ASAN_INST_TEST_SOURCES asan_globals_test.cc asan_test.cc) 168 add_library(asan_noinst_test OBJECT ${ASAN_NOINST_TEST_SOURCES}) 169 set_target_compile_flags(asan_noinst_test ${ASAN_UNITTEST_COMMON_CFLAGS}) 170 add_library(asan_inst_test OBJECT 171 ${ASAN_INST_TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE}) 172 set_target_compile_flags(asan_inst_test ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) 173 add_executable(AsanTest 174 $<TARGET_OBJECTS:asan_noinst_test> 175 $<TARGET_OBJECTS:asan_inst_test> 176 ) 177 # Setup correct output directory and link flags. 178 get_unittest_directory(OUTPUT_DIR) 179 set_target_properties(AsanTest PROPERTIES 180 RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR}) 181 set_target_link_flags(AsanTest ${ASAN_LINK_FLAGS}) 182 target_link_libraries(AsanTest clang_rt.asan-arm-android) 183 # Add unit test to test suite. 184 add_dependencies(AsanUnitTests AsanTest) 185endif() 186