# The SOVERSION should be updated only if a change is made to the libclang
# ABI, and when it is updated, it should be updated to the current
# LLVM_VERSION_MAJOR.
# Please also see clang/tools/libclang/libclang.map

# This option defaults to CLANG_FORCE_MATCHING_LIBCLANG_SOVERSION
# to ON - which means that it by default matches CLANG_VERSION_MAJOR
#
# TODO: This should probably not be a option going forward but we
# we should commit to a way to do it. But due to getting this out
# in LLVM 15.x we opted for a option.
set(LIBCLANG_SOVERSION_ARG)
if(NOT CLANG_FORCE_MATCHING_LIBCLANG_SOVERSION)
  set(LIBCLANG_SOVERSION_ARG SOVERSION 13)
endif()

# TODO: harmonize usage of LIBCLANG_SOVERSION / LIBCLANG_LIBARY_VERSION
#       below; this was added under time-pressure to avoid reverting the
#       better default from LLVM 14 for LLVM 15.0.0-rc3, hence no time
#       to clean up previous inconsistencies.

set(SOURCES
  ARCMigrate.cpp
  BuildSystem.cpp
  CIndex.cpp
  CIndexCXX.cpp
  CIndexCodeCompletion.cpp
  CIndexDiagnostic.cpp
  CIndexHigh.cpp
  CIndexInclusionStack.cpp
  CIndexUSRs.cpp
  CIndexer.cpp
  CXComment.cpp
  CXCursor.cpp
  CXExtractAPI.cpp
  CXIndexDataConsumer.cpp
  CXCompilationDatabase.cpp
  CXLoadedDiagnostic.cpp
  CXSourceLocation.cpp
  CXStoredDiagnostic.cpp
  CXString.cpp
  CXType.cpp
  Indexing.cpp
  FatalErrorHandler.cpp
  Rewrite.cpp

  ADDITIONAL_HEADERS
  CIndexDiagnostic.h
  CIndexer.h
  CXCursor.h
  CXLoadedDiagnostic.h
  CXSourceLocation.h
  CXString.h
  CXTranslationUnit.h
  CXType.h
  Index_Internal.h
  ../../include/clang-c/Index.h
  )

set(LIBS
  clangAST
  clangBasic
  clangDriver
  clangExtractAPI
  clangFrontend
  clangIndex
  clangLex
  clangRewrite
  clangSema
  clangSerialization
  clangTooling
)

if (CLANG_ENABLE_ARCMT)
  list(APPEND LIBS clangARCMigrate)
endif ()

if (HAVE_LIBDL)
  list(APPEND LIBS ${CMAKE_DL_LIBS})
elseif (CLANG_BUILT_STANDALONE)
  find_library(DL_LIBRARY_PATH dl)
  if (DL_LIBRARY_PATH)
    list(APPEND LIBS dl)
  endif ()
endif ()

option(LIBCLANG_BUILD_STATIC
  "Build libclang as a static library (in addition to a shared one)" OFF)

set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_BINARY_DIR}/libclang-generic.exports)
set(LIBCLANG_VERSION_SCRIPT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libclang.map)

if(MSVC)
  # Avoid LNK4197 by not specifying libclang.exports here.
  # Each functions is exported as "dllexport" in include/clang-c.
  # KB835326
  set(LLVM_EXPORTED_SYMBOL_FILE)
endif()

if (UNIX AND NOT APPLE)
  set(LLVM_EXPORTED_SYMBOL_FILE)
  set(USE_VERSION_SCRIPT ${LLVM_HAVE_LINK_VERSION_SCRIPT})
endif()

if (LLVM_EXPORTED_SYMBOL_FILE)
  add_custom_command(OUTPUT ${LLVM_EXPORTED_SYMBOL_FILE}
                     COMMAND "${Python3_EXECUTABLE}"
                       ARGS ${CMAKE_CURRENT_SOURCE_DIR}/linker-script-to-export-list.py
                            ${LIBCLANG_VERSION_SCRIPT_FILE}
                            ${LLVM_EXPORTED_SYMBOL_FILE}
                     DEPENDS ${LIBCLANG_VERSION_SCRIPT_FILE})
endif()

if(LLVM_ENABLE_PIC OR (WIN32 AND NOT LIBCLANG_BUILD_STATIC))
  set(ENABLE_SHARED SHARED)
endif()

if(NOT LLVM_ENABLE_PIC OR LIBCLANG_BUILD_STATIC)
  set(ENABLE_STATIC STATIC)
endif()

if (MSVC AND ENABLE_SHARED AND ENABLE_STATIC)
  unset(ENABLE_STATIC)
endif()

if(MSVC)
  set(output_name "libclang")
else()
  set(output_name "clang")
endif()

# libclang requires headers which need _ALL_SOURCE to build on AIX
if (UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
    remove_definitions("-D_XOPEN_SOURCE=700")
endif()

add_clang_library(libclang ${ENABLE_SHARED} ${ENABLE_STATIC} INSTALL_WITH_TOOLCHAIN
  OUTPUT_NAME ${output_name}
  ${SOURCES}

  DEPENDS
  ClangDriverOptions
  clang-resource-headers

  LINK_LIBS
  ${LIBS}

  LINK_COMPONENTS
  ${LLVM_TARGETS_TO_BUILD}
  Core
  Support
  TargetParser
  )

if(ENABLE_STATIC)
  foreach(name libclang obj.libclang libclang_static)
    if (TARGET ${name})
      target_compile_definitions(${name} PUBLIC CINDEX_NO_EXPORTS)
    endif()
  endforeach()
endif()

if(ENABLE_SHARED)
  if(WIN32)
    set_target_properties(libclang
      PROPERTIES
      VERSION ${LIBCLANG_LIBRARY_VERSION}
      DEFINE_SYMBOL _CINDEX_LIB_)
  elseif(APPLE)
    set(LIBCLANG_LINK_FLAGS " -Wl,-compatibility_version -Wl,1")
    set(LIBCLANG_LINK_FLAGS "${LIBCLANG_LINK_FLAGS} -Wl,-current_version -Wl,${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")

    set_property(TARGET libclang APPEND_STRING PROPERTY
                 LINK_FLAGS ${LIBCLANG_LINK_FLAGS})
  else()
    set_target_properties(libclang
      PROPERTIES
      VERSION ${LIBCLANG_LIBRARY_VERSION}
      DEFINE_SYMBOL _CINDEX_LIB_)
    # FIXME: _CINDEX_LIB_ affects dllexport/dllimport on Win32.
    if(LLVM_ENABLE_MODULES AND NOT WIN32)
      target_compile_options(libclang PRIVATE
        "-fmodules-ignore-macro=_CINDEX_LIB_"
        )
    endif()
  endif()
  if (USE_VERSION_SCRIPT)
    target_link_options(libclang PRIVATE "-Wl,--version-script,${CMAKE_CURRENT_SOURCE_DIR}/libclang.map")
    # The Solaris 11.4 linker supports a subset of GNU ld version scripts,
    # but requires a special option to enable it.
    if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
      target_link_options(libclang PRIVATE "-Wl,-z,gnu-version-script-compat")
    endif()
    # Ensure that libclang.so gets rebuilt when the linker script changes.
    set_property(SOURCE ARCMigrate.cpp APPEND PROPERTY
                 OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libclang.map)

    set_target_properties(libclang PROPERTIES
                          VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX}
                          ${LIBCLANG_SOVERSION_ARG})
  endif()
endif()

if(INTERNAL_INSTALL_PREFIX)
  set(LIBCLANG_HEADERS_INSTALL_DESTINATION "${INTERNAL_INSTALL_PREFIX}/include")
else()
  set(LIBCLANG_HEADERS_INSTALL_DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
endif()

install(DIRECTORY ../../include/clang-c
  COMPONENT libclang-headers
  DESTINATION "${LIBCLANG_HEADERS_INSTALL_DESTINATION}"
  FILES_MATCHING
  PATTERN "*.h"
  )

# LLVM_DISTRIBUTION_COMPONENTS requires that each component have both a
# component and an install-component target, so add a dummy libclang-headers
# target to allow using it in LLVM_DISTRIBUTION_COMPONENTS.
add_custom_target(libclang-headers)
set_target_properties(libclang-headers PROPERTIES FOLDER "Misc")

if (NOT LLVM_ENABLE_IDE)
  add_llvm_install_targets(install-libclang-headers
                           COMPONENT libclang-headers)
endif()

# Create a target to install the python bindings to make them easier to
# distribute.  Since the bindings are over libclang, which is installed
# unbundled to the clang version, follow suit.
foreach(PythonVersion ${CLANG_PYTHON_BINDINGS_VERSIONS})
  install(DIRECTORY
            ${CMAKE_CURRENT_SOURCE_DIR}/../../bindings/python/clang
          COMPONENT
            libclang-python-bindings
          DESTINATION
            "lib${LLVM_LIBDIR_SUFFIX}/python${PythonVersion}/site-packages")
endforeach()
if(NOT LLVM_ENABLE_IDE)
  add_custom_target(libclang-python-bindings)
  add_llvm_install_targets(install-libclang-python-bindings
                           COMPONENT
                             libclang-python-bindings)
endif()

