cmake_minimum_required(VERSION 3.11.2)

project(cmb-superbuild)

list(INSERT CMAKE_MODULE_PATH 0
  "${CMAKE_CURRENT_LIST_DIR}/cmake")

macro (superbuild_setup_variables)
  include(SuperbuildVersionMacros)

  if (cmb_SOURCE_SELECTION STREQUAL "git")
    # Assuming master; just use the latest version, but let the user set their
    # own version in case it is actually a branch from some other version.
    set(CMB_VERSION_DEFAULT  "<FETCH_FROM_GIT>"
      CACHE STRING "The default version of CMB to use if it cannot be detected")
    if (CMB_VERSION_DEFAULT STREQUAL "<FETCH_FROM_GIT>")
      include(cmbVersion)
      set(CMB_VERSION_DEFAULT "${cmb_version_major}.${cmb_version_minor}.${cmb_version_patch}")
    endif ()
    mark_as_advanced(CMB_VERSION_DEFAULT)
    set(cmb_default_version "${CMB_VERSION_DEFAULT}")
  elseif (cmb_SOURCE_SELECTION STREQUAL "source")
    # If it is a git repo, we'll get it that way. Otherwise, we will look at the
    # `version.txt` in the checkout.
    set(cmb_default_version "")
  else ()
    # The selection is the version number; use it.
    set(cmb_default_version "${cmb_SOURCE_SELECTION}")
  endif()
  superbuild_set_version_variables(cmb "${cmb_default_version}" "cmb-version.cmake" "version.txt")
  set(cmb_version "${cmb_version_major}.${cmb_version_minor}")

  if (smtk_SOURCE_SELECTION STREQUAL "git")
    # Assuming master; just use the latest version, but let the user set their
    # own version in case it is actually a branch from some other version.
    set(SMTK_VERSION_DEFAULT  "<FETCH_FROM_GIT>"
      CACHE STRING "The default version of SMTK to use if it cannot be detected")
    if (SMTK_VERSION_DEFAULT STREQUAL "<FETCH_FROM_GIT>")
      include(smtkVersion)
      set(SMTK_VERSION_DEFAULT "${smtk_version_major}.${smtk_version_minor}.${smtk_version_patch}")
    endif ()
    mark_as_advanced(SMTK_VERSION_DEFAULT)
    set(smtk_default_version "${SMTK_VERSION_DEFAULT}")
  elseif (smtk_SOURCE_SELECTION STREQUAL "source")
    # If it is a git repo, we'll get it that way. Otherwise, we will look at the
    # `version.txt` in the checkout.
    set(smtk_default_version "")
  else ()
    # The selection is the version number; use it.
    set(smtk_default_version "${smtk_SOURCE_SELECTION}")
  endif()
  superbuild_set_version_variables(smtk "${smtk_default_version}" "smtk-version.cmake" "version.txt")
  set(smtk_version "${smtk_version_major}.${smtk_version_minor}")

  if (paraview_SOURCE_SELECTION STREQUAL "git")
    include(paraviewVersion)
    set(paraview_default_version "${paraview_version_major}.${paraview_version_minor}.${paraview_version_patch}")
  elseif (paraview_SOURCE_SELECTION STREQUAL "master")
    # Assuming master; just use the latest version, but let the user set their
    # own version in case it is actually a branch from some other version.
    set(PARAVIEW_VERSION_DEFAULT "<FETCH_FROM_GIT>"
      CACHE STRING "The default version of ParaView to use if it cannot be detected")
    if (PARAVIEW_VERSION_DEFAULT STREQUAL "<FETCH_FROM_GIT>")
      include(paraviewVersion)
      set(PARAVIEW_VERSION_DEFAULT "${paraview_version_major}.${paraview_version_minor}.${paraview_version_patch}")
    endif ()
    mark_as_advanced(PARAVIEW_VERSION_DEFAULT)
    set(paraview_default_version "${PARAVIEW_VERSION_DEFAULT}")
  elseif (paraview_SOURCE_SELECTION STREQUAL "for-v6.3.0")
    include(paraviewVersion)
    set(paraview_default_version "${paraview_version_major}.${paraview_version_minor}.${paraview_version_patch}")
  elseif (paraview_SOURCE_SELECTION STREQUAL "source")
    # If it is a git repo, we'll get it that way. Otherwise, we will look at the
    # `version.txt` in the checkout.
    set(paraview_default_version "")
  endif ()
  superbuild_set_version_variables(paraview "${paraview_default_version}" "paraview-version.cmake" "version.txt")
  set(paraview_version "${paraview_version_major}.${paraview_version_minor}")

  superbuild_set_version_variables(vtk "9.0.0" "vtk-version.cmake")
  set(vtk_version "${vtk_version_major}.${vtk_version_minor}")

  if (aeva_SOURCE_SELECTION STREQUAL "git")
    # Assuming master; just use the latest version, but let the user set their
    # own version in case it is actually a branch from some other version.
    set(AEVA_VERSION_DEFAULT  "<FETCH_FROM_GIT>"
      CACHE STRING "The default version of AEVA to use if it cannot be detected")
    if (AEVA_VERSION_DEFAULT STREQUAL "<FETCH_FROM_GIT>")
      include(aevaVersion)
      set(AEVA_VERSION_DEFAULT "${aeva_version_major}.${aeva_version_minor}.${aeva_version_patch}")
    endif ()
    mark_as_advanced(AEVA_VERSION_DEFAULT)
    set(aeva_default_version "${AEVA_VERSION_DEFAULT}")
  elseif (aeva_SOURCE_SELECTION STREQUAL "source")
    # If it is a git repo, we'll get it that way. Otherwise, we will look at the
    # `version.txt` in the checkout.
    set(aeva_default_version "")
  else ()
    # The selection is the version number; use it.
    set(aeva_default_version "${aeva_SOURCE_SELECTION}")
  endif()
  superbuild_set_version_variables(aeva "${aeva_default_version}" "aeva-version.cmake" "version.txt")
  set(aeva_version "${aeva_version_major}.${aeva_version_minor}")
endmacro ()

function (superbuild_find_projects var)
  include(CMBSuperbuildMacros)

  set(projects
    boost
    bzip2
    cmb
    cmbusersguide
    cmbworkflows
    cumulus
    cxx11
    eigen
    fortran
    freetype
    ftgl
    gdal
    hdf5
    itk
    itkvtkglue
    lapack
    las
    libarchive
    matplotlib
    moab
    netcdf
    nlohmannjson
    numpy
    occt
    opencv
    paraview
    paraviewweb
    paraviewwebvisualizer
    paraviewweblightviz
    pegtl
    png
    protobuf
    pyarc
    pybind11
    python
    python2
    python3
    pythoncycler
    pythondateutil
    pythondiskcache
    pythongirderclient
    pythonkiwisolver
    pythonpyparsing
    pythonrequests
    pythonrequeststoolbelt
    pythonsetuptools
    pythonsix
    pytz
    qt5
    remus
    rggsession
    smtk
    smtkusersguide
    szip
    vtk
    vtkonly
    vxl
    zeromq
    zlib)

  if (NOT WIN32)
    list(APPEND projects
      ffi
      fontconfig
      gperf
      libxml2
      meshkit
      utillinux)
  endif ()

  if (WIN32)
    list(APPEND projects
      ftjam
      pythonsetuptools
      pywin32)
  endif ()

  if (NOT DEVELOPER_MODE_smtk)
    list(APPEND projects
      smtkprojectmanager
      smtkresourcemanagerstate)
  endif ()

  list(APPEND projects
    aeva
    aevasession
  )

  # For now it's a convenient option to control smtk documentation.
  option(ENABLE_DOCUMENTATION "Enable smtk documentation" ON)

  option(USE_NONFREE_COMPONENTS "Enable the non-free parts of the superbuild" OFF)
  mark_as_advanced(USE_NONFREE_COMPONENTS)
  if (USE_NONFREE_COMPONENTS)
    list(APPEND projects
      capstone
      cubit
      triangle)
  endif ()

  # Capstone and Cubit are closed-source programs to which Kitware developers
  # have access. We provide logic for situating these programs into our
  # superbuild for development purposes only. These packages are not bundled or
  # distributed.
  set(KW_SHARE "" CACHE PATH "Location of Kitware-internal share directory.")

  if (NOT (capstone_enabled OR cubit_enabled))
    mark_as_advanced(KW_SHARE)
  endif ()

  set("${var}"
    ${projects}
    PARENT_SCOPE)
endfunction ()

function (superbuild_sanity_check)
  if (vtkonly_enabled AND paraview_enabled)
    message(FATAL_ERROR
      "Only one of the following projects should be enabled: vtkonly, paraview.")
  endif ()
  if (NOT smtk_enabled AND NOT cmb_enabled AND NOT aeva_enabled)
    message(FATAL_ERROR
      "At least one of the following projects must be enabled: cmb, smtk, aeva.")
  endif ()
endfunction ()

function (superbuild_add_packaging)
  if (NOT (cmb_enabled OR aeva_enabled) OR DEVELOPER_MODE_cmb)
    return ()
  endif ()

  if (WIN32)
    set(generators
      ZIP)
  elseif (APPLE)
    set(generators
      DragNDrop)
  else ()
    set(generators
      TGZ)
  endif ()

  # Force qt SVG support, so CMB/ParaView can use SVG icons
  set(qt5_ENABLE_SVG ON CACHE INTERNAL "CMB/ParaView requires SVG support")

  if (UNIX AND NOT APPLE AND NOT USE_SYSTEM_qt5)
    set(Qt5_DIR "${superbuild_install_location}/lib/cmake/Qt5")
    set(qt5_version "${qt5_SOURCE_SELECTION}")
  else ()
    list(APPEND superbuild_export_variables
      Qt5_DIR)
    find_package(Qt5 QUIET REQUIRED COMPONENTS Core)
    set(qt5_version "${Qt5Core_VERSION_MAJOR}.${Qt5Core_VERSION_MINOR}")
  endif ()
  list(APPEND superbuild_export_variables
    qt5_version)

  list(APPEND superbuild_export_variables
    BOOST_ADDITIONAL_LIBRARIES)

  include(cmb.suffix)
  list(APPEND superbuild_export_variables
    CMB_PACKAGE_SUFFIX)

  if (cmb_enabled)
    set(CMB_PACKAGE_FILE_NAME ""
      CACHE STRING "If set, overrides the generated filename for the package")
    list(APPEND superbuild_export_variables
      CMB_PACKAGE_FILE_NAME)

    foreach (generator IN LISTS generators)
      superbuild_add_extra_package_test(modelbuilder "${generator}"
        LABELS  "CMB"
        TIMEOUT 6400)
    endforeach ()
  endif ()

  if (aeva_enabled)
    set(AEVA_PACKAGE_FILE_NAME ""
      CACHE STRING "If set, overrides the generated filename for the package")
    list(APPEND superbuild_export_variables
      AEVA_PACKAGE_FILE_NAME)

    foreach (generator IN LISTS generators)
      superbuild_add_extra_package_test(aeva "${generator}"
        LABELS  "AEVA"
        TIMEOUT 6400)
    endforeach ()
  endif ()

endfunction ()

macro (superbuild_setup_tests)
  if (cmb_enabled)
    set(DROP_LOCATION "/submit.php?project=CMB")
  elseif (smtk_enabled)
    set(DROP_LOCATION "/submit.php?project=SMTK")
  endif ()
endmacro ()

function (superbuild_add_tests)
  set_property(GLOBAL APPEND
    PROPERTY
      superbuild_test_projects cmb smtk)
endfunction ()

# Default Qt5 to ON
set(_superbuild_default_qt5 ON)

set(qt5_skip_modules
  qtconnectivity
  qtgamepad
  qtlocation
  qtmultimedia
  qtsensors
  qtserialport
  qtwayland
  qtwebchannel
  qtwebengine
  qtwebsockets)

set(BOOST_ADDITIONAL_LIBRARIES "" CACHE STRING "Additional boost libraries to build and package")
mark_as_advanced(BOOST_ADDITIONAL_LIBRARIES)

set(boost_minimum_version 1.64.0)
set(boost_libraries
  atomic
  chrono
  date_time
  filesystem
  iostreams
  log
  program_options
  regex
  serialization
  system
  thread
  timer
  ${BOOST_ADDITIONAL_LIBRARIES})

configure_file(
  "${CMAKE_CURRENT_LIST_DIR}/cmake/CTestCustom.cmake.in"
  "${CMAKE_CURRENT_BINARY_DIR}/CTestCustom-cmb.cmake"
  @ONLY)

if (__BUILDBOT_INSTALL_LOCATION)
  set(superbuild_install_location "${__BUILDBOT_INSTALL_LOCATION}")
endif ()

set(suppress_projects
  boost
  freetype
  ftgl
  gdal
  hdf5
  netcdf
  numpy
  occt
  png
  pybind11
  szip
  vxl
  zeromq
  zlib)
foreach (suppress_project IN LISTS suppress_projects)
  set("_superbuild_suppress_${suppress_project}_output" ON)
endforeach ()

list(APPEND superbuild_version_files
  "${CMAKE_CURRENT_LIST_DIR}/versions.cmake")
list(APPEND superbuild_ctest_custom_files
  "${CMAKE_CURRENT_BINARY_DIR}/CTestCustom-cmb.cmake")
list(APPEND superbuild_project_roots
  "${CMAKE_CURRENT_LIST_DIR}/projects")
add_subdirectory(superbuild)
