cmake_minimum_required(VERSION 3.13.4)

# Add path for custom modules.
set(CMAKE_MODULE_PATH
  ${CMAKE_MODULE_PATH}
  "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
  )

# If we are not building as part of LLVM, build LLDB as a standalone project,
# using LLVM as an external library.
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
  project(lldb)
  include(LLDBStandalone)

  set(CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard to conform to")
  set(CMAKE_CXX_STANDARD_REQUIRED YES)
  set(CMAKE_CXX_EXTENSIONS NO)
endif()

include(LLDBConfig)
include(AddLLDB)

# Define the LLDB_CONFIGURATION_xxx matching the build type.
if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" )
  add_definitions(-DLLDB_CONFIGURATION_DEBUG)
endif()

if (WIN32)
  add_definitions(-D_ENABLE_EXTENDED_ALIGNED_STORAGE)
endif()

if (LLDB_ENABLE_PYTHON)
  execute_process(
    COMMAND ${Python3_EXECUTABLE}
        -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(True, False, ''))"
    OUTPUT_VARIABLE LLDB_PYTHON_DEFAULT_RELATIVE_PATH
    OUTPUT_STRIP_TRAILING_WHITESPACE)

  file(TO_CMAKE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH} LLDB_PYTHON_DEFAULT_RELATIVE_PATH)
  set(LLDB_PYTHON_RELATIVE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH}
    CACHE STRING "Path where Python modules are installed, relative to install prefix")
endif ()

if (LLDB_ENABLE_PYTHON OR LLDB_ENABLE_LUA)
  add_subdirectory(bindings)
endif ()

# We need the headers generated by instrinsics_gen before we can compile
# any source file in LLDB as the imported Clang modules might include
# some of these generated headers. This approach is copied from Clang's main
# CMakeLists.txt, so it should kept in sync the code in Clang which was added
# in llvm-svn 308844.
if(LLVM_ENABLE_MODULES)
  list(APPEND LLVM_COMMON_DEPENDS intrinsics_gen)
endif()

if(CMAKE_CROSSCOMPILING AND LLDB_BUILT_STANDALONE)
  set(LLVM_USE_HOST_TOOLS ON)
  include(CrossCompile)
  if (NOT NATIVE_LLVM_DIR OR NOT NATIVE_Clang_DIR)
    message(FATAL_ERROR
      "Crosscompiling standalone requires the variables NATIVE_{CLANG,LLVM}_DIR
      for building the native lldb-tblgen used during the build process.")
  endif()
  llvm_create_cross_target(lldb NATIVE "" Release
    -DLLVM_DIR=${NATIVE_LLVM_DIR}
    -DClang_DIR=${NATIVE_Clang_DIR})
endif()

# TableGen
add_subdirectory(utils/TableGen)

add_subdirectory(source)
add_subdirectory(tools)
add_subdirectory(docs)

if (LLDB_ENABLE_PYTHON)
  if(LLDB_BUILD_FRAMEWORK)
    set(lldb_python_target_dir "${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework/Resources/Python/lldb")
  else()
    set(lldb_python_target_dir "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_PYTHON_RELATIVE_PATH}/lldb")
  endif()
  get_target_property(lldb_python_bindings_dir swig_wrapper_python BINARY_DIR)
  finish_swig_python("lldb-python" "${lldb_python_bindings_dir}" "${lldb_python_target_dir}")
endif()

option(LLDB_INCLUDE_TESTS "Generate build targets for the LLDB unit tests." ${LLVM_INCLUDE_TESTS})
if(LLDB_INCLUDE_TESTS)
  add_subdirectory(test)
  add_subdirectory(unittests)
  add_subdirectory(utils)
endif()

if(LLDB_BUILT_STANDALONE AND NOT LLVM_ENABLE_IDE)
  llvm_distribution_add_targets()
endif()
