## ---------------------------------------------------------------------
##
## Copyright (C) 2017 by the deal.II authors
##
## This file is part of the deal.II library.
##
## The deal.II library is free software; you can use it, redistribute
## it, and/or modify it under the terms of the GNU Lesser General
## Public License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
## The full text of the license can be found in the file LICENSE at
## the top level of the deal.II distribution.
##
## ---------------------------------------------------------------------

#
# Usage:
#   SETUP_UNITY_TARGET("${_list_of_unity_source_files}" _includes_per_unity_file _output_src)
#
# This macro sets up some number of unity build targets given a list of files
# and the number of files to be included per unity file. It generates the unity
# build files and appends their names to _output_src.
#
MACRO(SETUP_UNITY_TARGET _unity_include_src _n_includes_per_unity_file _output_src)
  #
  # The unity build files need access to the original source files:
  #
  INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})

  SET(_file_index 0)
  FOREACH(_unity_file ${_unity_include_src})
    MATH(EXPR _unity_prefix_index "${_file_index} / ${_n_includes_per_unity_file}")
    #
    # Get around the fact that CMake does not support nested lists by generating
    # a file name and then storing that file name in a list (which we will
    # uniquify later)
    #
    SET(_unity_prefix "unity_${_unity_prefix_index}")
    LIST(APPEND _unity_prefixes ${_unity_prefix})
    LIST(APPEND ${_unity_prefix} ${_unity_file})

    MATH(EXPR _file_index "${_file_index} + 1")
  ENDFOREACH()

  LIST(REMOVE_DUPLICATES _unity_prefixes)

  FOREACH(_unity_prefix ${_unity_prefixes})
    SET(_unity_file_name "${CMAKE_CURRENT_BINARY_DIR}/${_unity_prefix}.cc")
    SET(_tmp_unity_file_name "${CMAKE_CURRENT_BINARY_DIR}/${_unity_prefix}_tmp.cc")

    #
    # Note the CMake weirdness: _output_src is actually a string containing the
    # variable name since we are in a macro...
    #
    SET(${_output_src}
      ${${_output_src}}
      ${_unity_file_name}
      )
    FILE(WRITE "${_tmp_unity_file_name}"
"// This file was automatically generated by the deal.II CMake configuration as
// part of the unity build subsystem. Please do not edit this file directly;
// instead, make appropriate changes to the relevant CMakeLists.txt file.\n\n"
      )
    FOREACH(_unity_file ${${_unity_prefix}})
      FILE(APPEND "${_tmp_unity_file_name}" "#include \"${_unity_file}\"\n")
    ENDFOREACH()

    #
    # CMake regenerates all unity files as part of the configuration process,
    # even though they usually have not changed. Avoid some recompilation by
    # using the CONFIGURE_FILE command, which won't update the time stamp unless
    # the content has changed.
    #
    CONFIGURE_FILE(${_tmp_unity_file_name} ${_unity_file_name} COPYONLY)
  ENDFOREACH()
ENDMACRO()
