#### gem5-specific stuff
if(BUILD_GEM5)
  message(STATUS "[${PROJECT_NAME}] Building gem5 variant ...")
  SET(VARIANT gem5)

  set(gem5_src_dir       ${PROJECT_SOURCE_DIR}/simulators/gem5)
  set(gem5_wrapper       ${PROJECT_BINARY_DIR}/src/core/sal/gem5)
  set(gem5_build_config  build/ARM/gem5.debug)
  ## Determine the number of cores:
  set(core_count 0) # unknown
  # Linux:
  set(cpuinfo_file "/proc/cpuinfo")
  if(EXISTS "${cpuinfo_file}")
    file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$")
    list(LENGTH procs core_count)
  endif()
  # Mac:
  if(APPLE)
    find_program(cmd_sys_pro "system_profiler")
    if(cmd_sys_pro)
      execute_process(COMMAND ${cmd_sys_pro} OUTPUT_VARIABLE info)
      string(REGEX REPLACE "^.*Total Number Of Cores: ([0-9]+).*$" "\\1"
        core_count "${info}")
    endif()
  endif()
  MATH(EXPR VAR "${core_count}+1") # CPU++
  MESSAGE(STATUS "Using ${core_count} core(s) for compiling with scons ...")

  # FIXMEs:
  # - ${core_count} should be derived from the parent make -jX parameter
  # - make ${gem5_build_config} configurable in CMake
  #   (alternative: gem5_build_config is set based on the CMake build
  #    config, e.g., "Debug" or "Release")
  # - Ideally, there is no additional "gem5-clean" target. Instead,
  #   calling "make clean" should also invoke a clean command in the
  #   gem5 root dir. This seems easy for "make only" projects--things
  #   get shaky due to "scons".

  # Enable ExternalProject CMake module (located in $FAIL/cmake/)
  include(ExternalProjectGem5Specific)

  add_custom_target(gem5-force-re-linking
    COMMAND @echo "Removing gem5 binary and CMake build stamp ..."
    COMMAND rm "${gem5_src_dir}/${gem5_build_config}" -f
    COMMAND rm "${PROJECT_BINARY_DIR}/FailGem5_binary_external-prefix/src/FailGem5_binary_external-stamp/FailGem5_binary_external-build" -f
  )
  # WARNING: This requires a known (and "fixed") implementation of
  # ExternalProject_Add() because we enforce re-linking by deleting
  # some internal CMake time-stamp files generated by the external
  # project stuff. We therefore provide our own version
  # ("ExternalProjectGem5Specific") using a different name.

  # Generate gem5 headers using the scons build system (in our custom "dummy" mode):
  # This effectivly calls the whole gem5 toolchain but replaces the compiler, the
  # linker, ar and ranlib with usr/bin/true. It allows us to just generate the headers
  # which, in turn, are required for fail compilation. This target has no dependencies.
  ExternalProject_Add2_Gem5Specific(
    FailGem5_generation # the (unique) name of this custom target (= external project)
    # Disable update, patch and configure step:
    UPDATE_COMMAND ""
    PATCH_COMMAND ""
    CONFIGURE_COMMAND ""
    SOURCE_DIR ${gem5_src_dir}
    BINARY_DIR ${gem5_src_dir}
    BUILD_COMMAND scons ${gem5_build_config} --dummy
    # Disable install step (for now)
    INSTALL_COMMAND ""
  )

  # Use cmake's external project feature to build gem5 (and link FailGem5):
  ExternalProject_Add2_Gem5Specific(
    FailGem5_binary_external
    DEPENDS FailGem5_generation
    # Disable update, patch and configure step:
    UPDATE_COMMAND ""
    PATCH_COMMAND ""
    SOURCE_DIR ${gem5_src_dir}
    BINARY_DIR ${gem5_src_dir}
    CONFIGURE_COMMAND ""
    # Build gem5 using scons build system:
    BUILD_COMMAND scons "CXX=${CMAKE_CXX_COMPILER} -p ${gem5_src_dir} --Xcompiler" EXTRAS=${gem5_wrapper} ${gem5_build_config} -j${core_count}
    # Disable install step (for now)
    INSTALL_COMMAND ""
  )

  # Cleans up everything (gem5 and Fail related):
  add_custom_target(gem5-allclean
    COMMAND @echo "Cleaning Fail* and gem5 ..."
    COMMAND cd "${PROJECT_BINARY_DIR}/" && make clean
    COMMAND cd "${gem5_src_dir}/" && scons -c build/ARM
    COMMAND cd "${gem5_src_dir}/" && rm -rf build/
  )

  # Resolve header dependencies first (i.e., generate the header files):
  add_dependencies(fail-sal FailGem5_generation)
  # Always enforce re-linking (bugfix for cmake/scons):
  add_dependencies(fail gem5-force-re-linking)
  # Re-build/link gem5 if Fail code has changed:
  add_dependencies(FailGem5_binary_external fail)
endif(BUILD_GEM5)
