diff options
Diffstat (limited to 'unittests/CMakeLists.txt')
-rw-r--r-- | unittests/CMakeLists.txt | 162 |
1 files changed, 122 insertions, 40 deletions
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index d6e58183..ef052f9b 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -7,41 +7,128 @@ # #===------------------------------------------------------------------------===# -# Build GTest. We don't use a pre-built version due to -# https://github.com/google/googletest/blob/master/googletest/docs/FAQ.md#why-is-it-not-recommended-to-install-a-pre-compiled-copy-of-google-test-for-example-into-usrlocal -set(GTEST_SRC_DIR - "/usr/src/gtest" - CACHE - PATH - "Path to GTest source directory" -) +if (TARGET gtest AND TARGET gtest_main) + # try to reuse LLVM's targets + + message(WARNING "LLVM exports 'gtest' and 'gtest_main' targets (for Google " + "Test), so KLEE cannot create them. By default, KLEE will reuse " + "LLVM's 'gtest' and 'gtest_main' targets if they are available. This is, " + "however, only recommended if LLVM and KLEE were build with the same " + "compiler and linker flags to prevent any compatibility issues.\n" + "To prevent CMake from reusing the targets or to use a different version " + "of Google Test, try either of the following:\n" + "- Point LLVM_DIR to the directory containing the `LLVMConfig.cmake` file " + "of an installed copy of LLVM instead of a build tree.\n" + "- Pass -DLLVM_INCLUDE_TESTS=OFF to CMake when building LLVM. This " + "prevents building unit tests in LLVM (but not in KLEE) and exporting the " + "target to the build tree.") + + if (GTEST_SRC_DIR) + message(FATAL_ERROR "Cannot use GTEST_SRC_DIR when targets 'gtest' and " + "'gtest_main' are already defined.\n" + "Either reuse LLVM's Google Test setup by not setting GTEST_SRC_DIR or " + "choose one of the options to prevent LLVM from exporting these targets.") + endif() + + # check if it's really LLVM that exports them + list(FIND LLVM_EXPORTED_TARGETS "gtest" _GTEST_INDEX) + list(FIND LLVM_EXPORTED_TARGETS "test_main" _GTEST_MAIN_INDEX) + if (${_GTEST_INDEX} GREATER -1 AND ${_GTEST_MAIN_INDEX}) + message(STATUS "Google Test: Reusing LLVM's 'gtest' and 'gtest_main' targets.") + # in this case, only include directory has to be set + if (LLVM_BUILD_MAIN_SRC_DIR) + set(GTEST_INCLUDE_DIR + "${LLVM_BUILD_MAIN_SRC_DIR}/utils/unittest/googletest/include" + CACHE + PATH + "Path to Google Test include directory" + ) + endif() + else() + message(FATAL_ERROR "Reusing Google Test targets from LLVM failed:" + "LLVM_EXPORTED_TARGETS does not contain 'gtest' or 'gtest_main'.") + endif() +else() + # LLVM's targets are not reused + + if (NOT GTEST_SRC_DIR) + if (USE_CMAKE_FIND_PACKAGE_LLVM AND LLVM_BUILD_MAIN_SRC_DIR) + # build from LLVM's utils directory + # NOTE: This can only be done using USE_CMAKE_FIND_PACKAGE_LLVM as + # LLVM replaced Google Test's CMakeLists.txt with its own, + # requiring add_llvm_library() from AddLLVM.cmake. + message(STATUS "Google Test: Building from LLVM's source tree.") + + set(GTEST_INCLUDE_DIR + "${LLVM_BUILD_MAIN_SRC_DIR}/utils/unittest/googletest/include" + CACHE + PATH + "Path to Google Test include directory" + ) + + add_subdirectory("${LLVM_BUILD_MAIN_SRC_DIR}/utils/unittest/" + "${CMAKE_CURRENT_BINARY_DIR}/gtest_build") + + # add includes for LLVM's modifications + target_include_directories(gtest BEFORE PRIVATE ${LLVM_INCLUDE_DIRS}) + target_include_directories(gtest_main BEFORE PRIVATE ${LLVM_INCLUDE_DIRS}) + else() + # try to find Google Test, as GTEST_SRC_DIR is not manually specified + find_path(GTEST_SRC_DIR + "src/gtest.cc" + + HINTS + "/usr/src/gtest" + + # prevent CMake from finding gtest.cc in LLVM's utils directory + NO_DEFAULT_PATH -if (NOT EXISTS "${GTEST_SRC_DIR}") - message(FATAL_ERROR "GTest source directory \"${GTEST_SRC_DIR}\" cannot be found.\n" - "Try passing -DGTEST_SRC_DIR=<path_to_gtest_source> to cmake where " - "<path_to_gtest_source> is the path to the GoogleTest source tree.\n" - "Alternatively you can disable unit tests by passing " - "-DENABLE_UNIT_TESTS=OFF to cmake.") + DOC + "Path to Google Test source directory" + ) + endif() + endif() + + if (NOT (TARGET gtest AND TARGET gtest_main)) + # building from GTEST_SRC_DIR, not from LLVM's utils directory + find_path(GTEST_INCLUDE_DIR + "gtest/gtest.h" + + HINTS + "${GTEST_SRC_DIR}/include" + + NO_DEFAULT_PATH + + DOC + "Path to Google Test include directory" + ) + + if (NOT EXISTS "${GTEST_SRC_DIR}") + message(FATAL_ERROR "Google Test source directory \"${GTEST_SRC_DIR}\" " + "cannot be found.\n" + "Try passing -DGTEST_SRC_DIR=<path_to_gtest_source> to CMake where " + "<path_to_gtest_source> is the path to the Google Test source tree.\n" + "Alternatively, you can disable unit tests by passing " + "-DENABLE_UNIT_TESTS=OFF to CMake.") + endif() + message(STATUS "Google Test: Building from source.") + message(STATUS "GTEST_SRC_DIR: ${GTEST_SRC_DIR}") + + # Prevent Google Test from adding to our install target. + # Required for >= 1.8.0, but can only be disabled starting with 1.8.1 + set(GTEST_INSTALL OFF CACHE BOOL "disable installing Google Test" FORCE) + + # Build Google Test as part of our project + add_subdirectory(${GTEST_SRC_DIR} "${CMAKE_CURRENT_BINARY_DIR}/gtest_build") + endif() + + # build Google Test with KLEE's defines and compile flags + target_compile_definitions(gtest PRIVATE ${KLEE_COMPONENT_CXX_DEFINES}) + target_compile_definitions(gtest_main PRIVATE ${KLEE_COMPONENT_CXX_DEFINES}) + target_compile_options(gtest PRIVATE ${KLEE_COMPONENT_CXX_FLAGS}) + target_compile_options(gtest_main PRIVATE ${KLEE_COMPONENT_CXX_FLAGS}) endif() -# It's important that GTest is built with KLEE's compile flags -# so set them here. -set(_OLD_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") -foreach (f ${KLEE_COMPONENT_CXX_FLAGS}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${f}") -endforeach() -foreach (f ${KLEE_COMPONENT_CXX_DEFINES}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${f}") -endforeach() - -# Build GTest as part of our project -# FIXME: Prevent GTest from adding to our install target. -# This is a problem for GTest >= 1.8. I've filled a PR to fix the issue -# ( https://github.com/google/googletest/pull/921 ). If it gets accepted -# we can do `set(gtest_enable_install FALSE)` to fix this. -add_subdirectory(${GTEST_SRC_DIR} "${CMAKE_CURRENT_BINARY_DIR}/gtest_build") - -set(CMAKE_CXX_FLAGS "${_OLD_CMAKE_CXX_FLAGS}") # Restore the flags # This keeps track of all the unit test # targets so we can ensure they are built @@ -52,22 +139,17 @@ define_property(GLOBAL FULL_DOCS "KLEE unit tests" ) -set(GTEST_INCLUDE_DIR - "${GTEST_SRC_DIR}/include" - CACHE - PATH - "Path to GTest include directory" -) - if (NOT IS_DIRECTORY "${GTEST_INCLUDE_DIR}") message(FATAL_ERROR - "Cannot find GTest include directory \"${GTEST_INCLUDE_DIR}\"") + "Cannot find Google Test include directory \"${GTEST_INCLUDE_DIR}\"") endif() +message(STATUS "GTEST_INCLUDE_DIR: ${GTEST_INCLUDE_DIR}") function(add_klee_unit_test target_name) add_executable(${target_name} ${ARGN}) target_link_libraries(${target_name} PRIVATE gtest_main) target_include_directories(${target_name} BEFORE PRIVATE "${GTEST_INCLUDE_DIR}") + target_include_directories(${target_name} BEFORE PRIVATE ${KLEE_COMPONENT_EXTRA_INCLUDE_DIRS}) set_target_properties(${target_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/unittests/" |