FindClang.cmake 5.27 KB
Newer Older
Kevin Funk's avatar
Kevin Funk committed
1
2
3
# Detect Clang libraries
#
# Defines the following variables:
4
#  CLANG_FOUND                 - True if Clang was found
5
6
#  CLANG_INCLUDE_DIRS          - Where to find Clang includes
#  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
12
#  CLANG_CLANGFRONTEND_LIB     - Clang Frontend (C++) Library
#  CLANG_CLANGDRIVER_LIB       - Clang Driver (C++) Library
Kevin Funk's avatar
Kevin Funk committed
13
14
#  ...
#
15
16
#  CLANG_LIBS                  - All the Clang C++ libraries
#
Kevin Funk's avatar
Kevin Funk committed
17
18
# Uses the same include and library paths detected by FindLLVM.cmake
#
19
# See https://clang.llvm.org/docs/InternalsManual.html for full list of libraries
Kevin Funk's avatar
Kevin Funk committed
20

Kevin Funk's avatar
Kevin Funk committed
21
#=============================================================================
22
# Copyright 2014-2015 Kevin Funk <kfunk@kde.org>
Kevin Funk's avatar
Kevin Funk committed
23
24
25
26
27
28
29
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
30

Kevin Funk's avatar
Kevin Funk committed
31
32
#=============================================================================

33
set(KNOWN_VERSIONS 9 8 7 6.0 5.0 4.0 3.9 3.8)
34
35
36
37
38
39

foreach(version ${KNOWN_VERSIONS})
    if (LLVM_DIR OR (DEFINED Clang_FIND_VERSION AND Clang_FIND_VERSION VERSION_GREATER version))
        break()
    endif ()

40
    find_package(LLVM ${version})
41
endforeach()
Kevin Funk's avatar
Kevin Funk committed
42

43
44
45
46
47
48
49
50
if (${Clang_FIND_REQUIRED})
    if(NOT DEFINED Clang_FIND_VERSION)
        message(SEND_ERROR "Could not find Clang.")
    else()
        message("Found version ${Clang_FIND_VERSION}")
    endif()
endif()

Kevin Funk's avatar
Kevin Funk committed
51
52
set(CLANG_FOUND FALSE)

53
if (LLVM_FOUND AND LLVM_LIBRARY_DIRS)
54
55
  macro(FIND_AND_ADD_CLANG_LIB _libname_)
    string(TOUPPER ${_libname_} _prettylibname_)
56
57
    find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_} HINTS ${LLVM_LIBRARY_DIRS} ${ARGN})
    if (CLANG_${_prettylibname_}_LIB)
58
59
60
      set(CLANG_LIBS ${CLANG_LIBS} ${CLANG_${_prettylibname_}_LIB})
    endif()
  endmacro(FIND_AND_ADD_CLANG_LIB)
61

62
  FIND_AND_ADD_CLANG_LIB(clangFrontend)
63

64
  # note: On Windows there's 'libclang.dll' instead of 'clang.dll' -> search for 'libclang', too
Kevin Funk's avatar
Kevin Funk committed
65
  FIND_AND_ADD_CLANG_LIB(clang NAMES clang libclang) # LibClang: high-level C interface
66

67
68
69
70
71
  FIND_AND_ADD_CLANG_LIB(clangDriver)
  FIND_AND_ADD_CLANG_LIB(clangCodeGen)
  FIND_AND_ADD_CLANG_LIB(clangSema)
  FIND_AND_ADD_CLANG_LIB(clangChecker)
  FIND_AND_ADD_CLANG_LIB(clangAnalysis)
72
  FIND_AND_ADD_CLANG_LIB(clangRewriteFrontend)
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  FIND_AND_ADD_CLANG_LIB(clangRewrite)
  FIND_AND_ADD_CLANG_LIB(clangAST)
  FIND_AND_ADD_CLANG_LIB(clangParse)
  FIND_AND_ADD_CLANG_LIB(clangLex)
  FIND_AND_ADD_CLANG_LIB(clangBasic)
  FIND_AND_ADD_CLANG_LIB(clangARCMigrate)
  FIND_AND_ADD_CLANG_LIB(clangEdit)
  FIND_AND_ADD_CLANG_LIB(clangFrontendTool)
  FIND_AND_ADD_CLANG_LIB(clangSerialization)
  FIND_AND_ADD_CLANG_LIB(clangTooling)
  FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCheckers)
  FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCore)
  FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerFrontend)
  FIND_AND_ADD_CLANG_LIB(clangRewriteCore)
endif()
88

89
if(CLANG_LIBS OR CLANG_CLANG_LIB)
90
  set(CLANG_FOUND TRUE)
Kevin Funk's avatar
Kevin Funk committed
91
else()
92
  message(STATUS "Could not find any Clang libraries in ${LLVM_LIBRARY_DIRS}")
Kevin Funk's avatar
Kevin Funk committed
93
endif()
94
95

if(CLANG_FOUND)
96
97
  set(CLANG_LIBRARY_DIRS ${LLVM_LIBRARY_DIRS})
  set(CLANG_INCLUDE_DIRS ${LLVM_INCLUDE_DIRS})
98
  set(CLANG_VERSION ${LLVM_VERSION})
99

100
101
102
  # svn version of clang has a svn suffix "8.0.0svn" but installs the header in "8.0.0", without the suffix
  string(REPLACE "svn" "" CLANG_VERSION_CLEAN "${CLANG_VERSION}")

103
104
105
106
107
108
109
  find_path(CLANG_BUILTIN_DIR
            # cpuid.h because it is defined in ClangSupport constructor as valid clang builtin dir indicator
            NAMES "cpuid.h"
            PATHS "${CLANG_LIBRARY_DIRS}"
                  "${CLANG_INCLUDE_DIRS}"
            PATH_SUFFIXES "clang/${CLANG_VERSION}/include"
                          "../../../clang/${CLANG_VERSION}/include"
110
111
                          "clang/${CLANG_VERSION_CLEAN}/include"
                          "../../../clang/${CLANG_VERSION_CLEAN}/include"
112
113
114
115
116
117
118
119
            NO_DEFAULT_PATH
  )

  if (NOT CLANG_BUILTIN_DIR)
      message(FATAL_ERROR "Could not find Clang builtin directory")
  endif()
  get_filename_component(CLANG_BUILTIN_DIR ${CLANG_BUILTIN_DIR} ABSOLUTE)

120
121
122
123
124
125
  # check whether llvm-config comes from an install prefix
  execute_process(
    COMMAND ${LLVM_CONFIG_EXECUTABLE} --src-root
    OUTPUT_VARIABLE _llvmSourceRoot
    OUTPUT_STRIP_TRAILING_WHITESPACE
  )
126
  string(FIND "${LLVM_INCLUDE_DIRS}" "${_llvmSourceRoot}" _llvmIsInstalled)
127
  if (NOT _llvmIsInstalled)
128
129
130
131
132
    message(STATUS "Detected that llvm-config comes from a build-tree, adding more include directories for Clang")
    list(APPEND CLANG_INCLUDE_DIRS
         "${LLVM_INSTALL_PREFIX}/tools/clang/include" # build dir
         "${_llvmSourceRoot}/tools/clang/include"     # source dir
    )
133
134
  endif()

135
  message(STATUS "Found Clang (LLVM version: ${CLANG_VERSION})")
136
137
138
139
  message(STATUS "  Include dirs:        ${CLANG_INCLUDE_DIRS}")
  message(STATUS "  Clang libraries:     ${CLANG_LIBS}")
  message(STATUS "  Libclang C library:  ${CLANG_CLANG_LIB}")
  message(STATUS "  Builtin include dir: ${CLANG_BUILTIN_DIR}")
Kevin Funk's avatar
Kevin Funk committed
140
else()
141
  if(Clang_FIND_REQUIRED)
142
    message(FATAL_ERROR "Could NOT find Clang")
143
  endif()
Kevin Funk's avatar
Kevin Funk committed
144
endif()