diff options
Diffstat (limited to 'cmake/find_bitcode_compiler.cmake')
-rw-r--r-- | cmake/find_bitcode_compiler.cmake | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/cmake/find_bitcode_compiler.cmake b/cmake/find_bitcode_compiler.cmake new file mode 100644 index 00000000..615931f3 --- /dev/null +++ b/cmake/find_bitcode_compiler.cmake @@ -0,0 +1,96 @@ +#===------------------------------------------------------------------------===# +# +# The KLEE Symbolic Virtual Machine +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# +# +# This file tries to find compilers to build LLVM bitcode. +# It is implicitly dependent on `find_llvm.cmake` already being run in the +# same scope. +# +#===------------------------------------------------------------------------===# + +message(STATUS "Looking for bitcode compilers") + +find_program( + LLVMCC + NAMES "clang-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}" "clang" "llvm-gcc" + # Give the LLVM tools directory higher priority than the system directory. + HINTS "${LLVM_TOOLS_BINARY_DIR}" +) +if (LLVMCC) + message(STATUS "Found ${LLVMCC}") +else() + message(FATAL_ERROR "Failed to find C bitcode compiler") +endif() + +find_program( + LLVMCXX + NAMES "clang++-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}" "clang++" "llvm-g++" + # Give the LLVM tools directory higher priority than the system directory. + HINTS "${LLVM_TOOLS_BINARY_DIR}" +) +if (LLVMCXX) + message(STATUS "Found ${LLVMCXX}") +else() + message(FATAL_ERROR "Failed to find C++ bitcode compiler") +endif() + +# Check `llvm-dis` is available +set(LLVM_DIS_TOOL "${LLVM_TOOLS_BINARY_DIR}/llvm-dis") +if (NOT EXISTS "${LLVM_DIS_TOOL}") + message(FATAL_ERROR + "The llvm-dis tool cannot be found at \"${LLVM_DIS_TOOL}\"") +endif() + +# Test compiler +function(test_bitcode_compiler COMPILER SRC_EXT) + message(STATUS "Testing bitcode compiler ${COMPILER}") + set(SRC_FILE "${CMAKE_BINARY_DIR}/test_bitcode_compiler.${SRC_EXT}") + file(WRITE "${SRC_FILE}" "int main(int argc, char** argv) { return 0;}") + set(BC_FILE "${SRC_FILE}.bc") + execute_process( + COMMAND + "${COMPILER}" + "-c" + "-emit-llvm" + "-o" "${BC_FILE}" + "${SRC_FILE}" + RESULT_VARIABLE COMPILE_INVOKE_EXIT_CODE + ) + if ("${COMPILE_INVOKE_EXIT_CODE}" EQUAL 0) + message(STATUS "Compile success") + else() + message(FATAL_ERROR "Compilation failed") + endif() + + message(STATUS "Checking compatibility with LLVM ${LLVM_PACKAGE_VERSION}") + # Check if the LLVM version we are using is compatible + # with this compiler by invoking the `llvm-dis` tool + # on the generated bitcode. + set(LL_FILE "${SRC_FILE}.ll") + execute_process( + COMMAND + "${LLVM_DIS_TOOL}" + "-o" "${LL_FILE}" + "${BC_FILE}" + RESULT_VARIABLE LLVM_DIS_INVOKE_EXIT_CODE + ) + if ("${LLVM_DIS_INVOKE_EXIT_CODE}" EQUAL 0) + message(STATUS "\"${COMPILER}\" is compatible") + else() + message(FATAL_ERROR "\"${COMPILER}\" is not compatible with LLVM ${LLVM_PACKAGE_VERSION}") + endif() + + # Remove temporary files. It's okay to not remove these on failure + # as they will be useful for developer debugging. + file(REMOVE "${SRC_FILE}") + file(REMOVE "${BC_FILE}") + file(REMOVE "${LL_FILE}") +endfunction() + +test_bitcode_compiler("${LLVMCC}" "c") +test_bitcode_compiler("${LLVMCXX}" "cxx") |