|
| 1 | +# Detect Clang libraries |
| 2 | +# |
| 3 | +# Defines the following variables: |
| 4 | +# CLANG_FOUND - True if Clang was found |
| 5 | +# CLANG_INCLUDE_DIRS - Where to find Clang includes |
| 6 | +# CLANG_LIBRARY_DIRS - Where to find Clang libraries |
| 7 | +# CLANG_BUILTIN_DIR - Where to find Clang builtin includes |
| 8 | +# |
| 9 | +# CLANG_CLANG_LIB - Libclang C library |
| 10 | +# |
| 11 | +# CLANG_CLANGFRONTEND_LIB - Clang Frontend (C++) Library |
| 12 | +# CLANG_CLANGDRIVER_LIB - Clang Driver (C++) Library |
| 13 | +# ... |
| 14 | +# |
| 15 | +# CLANG_LIBS - All the Clang C++ libraries |
| 16 | +# |
| 17 | +# Uses the same include and library paths detected by FindLLVM.cmake |
| 18 | +# |
| 19 | +# See https://clang.llvm.org/docs/InternalsManual.html for full list of libraries |
| 20 | + |
| 21 | +#============================================================================= |
| 22 | +# Copyright 2014-2015 Kevin Funk <[email protected]> |
| 23 | +# |
| 24 | +# Distributed under the OSI-approved BSD License (the "License"); |
| 25 | +# see accompanying file Copyright.txt for details. |
| 26 | +# |
| 27 | +# This software is distributed WITHOUT ANY WARRANTY; without even the |
| 28 | +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| 29 | +# See the License for more information. |
| 30 | + |
| 31 | +#============================================================================= |
| 32 | + |
| 33 | +set(KNOWN_VERSIONS 16) |
| 34 | + |
| 35 | +foreach(version ${KNOWN_VERSIONS}) |
| 36 | + if(DEFINED Clang_FIND_VERSION AND Clang_FIND_VERSION VERSION_EQUAL version) |
| 37 | + find_package(LLVM ${version} PATHS ${LLVM_ROOT}) |
| 38 | + else() |
| 39 | + find_package(LLVM PATHS ${LLVM_ROOT}) |
| 40 | + endif() |
| 41 | +endforeach() |
| 42 | + |
| 43 | +if (${Clang_FIND_REQUIRED}) |
| 44 | + if(NOT DEFINED LLVM_FOUND) |
| 45 | + message(SEND_ERROR "Could not find LLVM (or Clang for that matter)") |
| 46 | + else() |
| 47 | + message("Found LLVM version ${LLVM_VERSION}") |
| 48 | + endif() |
| 49 | +endif() |
| 50 | + |
| 51 | +set(CLANG_FOUND FALSE) |
| 52 | + |
| 53 | +if(LLVM_FOUND AND LLVM_LIBRARY_DIRS) |
| 54 | + message("Searching for clang libraries...") |
| 55 | + macro(FIND_AND_ADD_CLANG_LIB _libname_) |
| 56 | + # message("Searching for ${LLVM_LIBRARY_DIRS}/lib${_libname_}-${Clang_FIND_VERSION}.so.1") |
| 57 | + string(TOUPPER ${_libname_} _prettylibname_) |
| 58 | + find_library(CLANG_${_prettylibname_}_LIB |
| 59 | + NAMES |
| 60 | + ${_libname_}-${Clang_FIND_VERSION}.so.1 lib${_libname_}-${Clang_FIND_VERSION}.so.1 |
| 61 | + ${_libname_}-${Clang_FIND_VERSION} lib${_libname_}-${Clang_FIND_VERSION} |
| 62 | + ${_libname_}.so.1 lib${_libname_}.so.1 |
| 63 | + ${_libname_} lib${_libname_} |
| 64 | + HINTS |
| 65 | + ${LLVM_LIBRARY_DIRS} ${ARGN}) |
| 66 | + if(CLANG_${_prettylibname_}_LIB) |
| 67 | + message("Found ${CLANG_${_prettylibname_}_LIB}") |
| 68 | + set(CLANG_LIBS ${CLANG_LIBS} ${CLANG_${_prettylibname_}_LIB}) |
| 69 | + endif() |
| 70 | + endmacro(FIND_AND_ADD_CLANG_LIB) |
| 71 | + |
| 72 | + FIND_AND_ADD_CLANG_LIB(clangFrontend) |
| 73 | + |
| 74 | + # note: On Windows there's 'libclang.dll' instead of 'clang.dll' -> search for 'libclang', too |
| 75 | + FIND_AND_ADD_CLANG_LIB(clang NAMES clang libclang clang-${Clang_FIND_VERSION} libclang-${Clang_FIND_VERSION}) # LibClang: high-level C interface |
| 76 | + |
| 77 | + FIND_AND_ADD_CLANG_LIB(clangDriver) |
| 78 | + FIND_AND_ADD_CLANG_LIB(clangCodeGen) |
| 79 | + FIND_AND_ADD_CLANG_LIB(clangSema) |
| 80 | + FIND_AND_ADD_CLANG_LIB(clangChecker) |
| 81 | + FIND_AND_ADD_CLANG_LIB(clangAnalysis) |
| 82 | + FIND_AND_ADD_CLANG_LIB(clangRewriteFrontend) |
| 83 | + FIND_AND_ADD_CLANG_LIB(clangRewrite) |
| 84 | + FIND_AND_ADD_CLANG_LIB(clangAST) |
| 85 | + FIND_AND_ADD_CLANG_LIB(clangParse) |
| 86 | + FIND_AND_ADD_CLANG_LIB(clangLex) |
| 87 | + FIND_AND_ADD_CLANG_LIB(clangBasic) |
| 88 | + FIND_AND_ADD_CLANG_LIB(clangARCMigrate) |
| 89 | + FIND_AND_ADD_CLANG_LIB(clangEdit) |
| 90 | + FIND_AND_ADD_CLANG_LIB(clangFrontendTool) |
| 91 | + FIND_AND_ADD_CLANG_LIB(clangSerialization) |
| 92 | + FIND_AND_ADD_CLANG_LIB(clangTooling) |
| 93 | + FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCheckers) |
| 94 | + FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCore) |
| 95 | + FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerFrontend) |
| 96 | + FIND_AND_ADD_CLANG_LIB(clangRewriteCore) |
| 97 | +endif() |
| 98 | + |
| 99 | +if(CLANG_LIBS OR CLANG_CLANG_LIB) |
| 100 | + set(CLANG_FOUND TRUE) |
| 101 | +else() |
| 102 | + message(STATUS "Could not find any Clang libraries in ${LLVM_LIBRARY_DIRS}") |
| 103 | +endif() |
| 104 | + |
| 105 | +if(CLANG_FOUND) |
| 106 | + set(CLANG_LIBRARY_DIRS ${LLVM_LIBRARY_DIRS}) |
| 107 | + set(CLANG_INCLUDE_DIRS ${LLVM_INCLUDE_DIRS}) |
| 108 | + set(CLANG_VERSION ${LLVM_VERSION}) |
| 109 | + |
| 110 | + # svn version of clang has a svn suffix "8.0.0svn" but installs the header in "8.0.0", without the suffix |
| 111 | + string(REPLACE "svn" "" CLANG_VERSION_CLEAN "${CLANG_VERSION}") |
| 112 | + # dito for git |
| 113 | + string(REPLACE "git" "" CLANG_VERSION_CLEAN "${CLANG_VERSION}") |
| 114 | + |
| 115 | + find_path(CLANG_BUILTIN_DIR |
| 116 | + # cpuid.h because it is defined in ClangSupport constructor as valid clang builtin dir indicator |
| 117 | + NAMES "cpuid.h" |
| 118 | + PATHS "${CLANG_LIBRARY_DIRS}" |
| 119 | + "${CLANG_INCLUDE_DIRS}" |
| 120 | + PATH_SUFFIXES "clang/${CLANG_VERSION}/include" |
| 121 | + "../../../clang/${CLANG_VERSION}/include" |
| 122 | + "clang/${CLANG_VERSION_CLEAN}/include" |
| 123 | + "../../../clang/${CLANG_VERSION_CLEAN}/include" |
| 124 | + NO_DEFAULT_PATH |
| 125 | + ) |
| 126 | + |
| 127 | + if (NOT CLANG_BUILTIN_DIR) |
| 128 | + message(FATAL_ERROR "Could not find Clang builtin directory") |
| 129 | + endif() |
| 130 | + get_filename_component(CLANG_BUILTIN_DIR ${CLANG_BUILTIN_DIR} ABSOLUTE) |
| 131 | + |
| 132 | + # check whether llvm-config comes from an install prefix |
| 133 | + execute_process( |
| 134 | + COMMAND ${LLVM_CONFIG_EXECUTABLE} --src-root |
| 135 | + OUTPUT_VARIABLE _llvmSourceRoot |
| 136 | + OUTPUT_STRIP_TRAILING_WHITESPACE |
| 137 | + ) |
| 138 | + string(FIND "${LLVM_INCLUDE_DIRS}" "${_llvmSourceRoot}" _llvmIsInstalled) |
| 139 | + if (NOT _llvmIsInstalled) |
| 140 | + message(STATUS "Detected that llvm-config comes from a build-tree, adding more include directories for Clang") |
| 141 | + list(APPEND CLANG_INCLUDE_DIRS |
| 142 | + "${LLVM_INSTALL_PREFIX}/tools/clang/include" # build dir |
| 143 | + ) |
| 144 | + |
| 145 | + # check whether the source is from llvm-project.git (currently recommended way to clone the LLVM projects) |
| 146 | + # contains all LLVM projects in the top-level directory |
| 147 | + get_filename_component(_llvmProjectClangIncludeDir ${_llvmSourceRoot}/../clang/include REALPATH) |
| 148 | + if (EXISTS ${_llvmProjectClangIncludeDir}) |
| 149 | + message(STATUS " Note: llvm-project.git structure detected, using different include path pointing into source dir") |
| 150 | + list(APPEND CLANG_INCLUDE_DIRS "${_llvmProjectClangIncludeDir}") # source dir |
| 151 | + else() |
| 152 | + list(APPEND CLANG_INCLUDE_DIRS "${_llvmSourceRoot}/tools/clang/include") # source dir |
| 153 | + endif() |
| 154 | + endif() |
| 155 | + |
| 156 | + # if the user specified LLVM_ROOT, use that and fail otherwise |
| 157 | + if (LLVM_ROOT) |
| 158 | + find_program(CLANG_EXECUTABLE NAMES clang HINTS ${LLVM_ROOT}/bin DOC "clang executable" NO_DEFAULT_PATH) |
| 159 | + elseif (NOT CLANG_EXECUTABLE) |
| 160 | + # find clang, prefer the one with a version suffix, e.g. clang-3.5 |
| 161 | + # note: FreeBSD installs clang as clang35 and so on |
| 162 | + # note: on some distributions, only 'clang' is shipped, so let's always try to fallback on that |
| 163 | + string(REPLACE "." "" Clang_FIND_VERSION_CONCAT ${Clang_FIND_VERSION}) |
| 164 | + find_program(CLANG_EXECUTABLE NAMES clang-${Clang_FIND_VERSION} clang${Clang_FIND_VERSION_CONCAT} clang DOC "clang executable") |
| 165 | + endif() |
| 166 | + |
| 167 | + message(STATUS "Found Clang (LLVM version: ${CLANG_VERSION})") |
| 168 | + message(STATUS " Include dirs: ${CLANG_INCLUDE_DIRS}") |
| 169 | + message(STATUS " Clang libraries: ${CLANG_LIBS}") |
| 170 | + message(STATUS " Libclang C library: ${CLANG_CLANG_LIB}") |
| 171 | + message(STATUS " Builtin include dir: ${CLANG_BUILTIN_DIR}") |
| 172 | + message(STATUS " Clang executable: ${CLANG_EXECUTABLE}") |
| 173 | +else() |
| 174 | + if(Clang_FIND_REQUIRED) |
| 175 | + message(FATAL_ERROR "Could NOT find Clang") |
| 176 | + endif() |
| 177 | +endif() |
0 commit comments