#-------------------------------------------------------------------------------
# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#-------------------------------------------------------------------------------

#[===[.rst:
Compiler abstraction for GCC
----------------------------
#]===]

include_guard(DIRECTORY)

if(NOT DEFINED CROSS_COMPILE AND NOT DEFINED ENV{CROSS_COMPILE})
	message(FATAL_ERROR "'CROSS_COMPILE' is not defined.")
endif()

set(CROSS_COMPILE $ENV{CROSS_COMPILE} CACHE STRING "Prefix of the cross-compiler commands")

find_program(_cross_compile_gcc NAMES ${CROSS_COMPILE}gcc ${CROSS_COMPILE}gcc.exe REQUIRED)
set(CMAKE_C_COMPILER ${_cross_compile_gcc})

#Official solution to disable compiler checks
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

#[===[.rst:
.. cmake:command:: compiler_preprocess_file

  .. code-block:: cmake

    compiler_preprocess_file(SRC file.c DST file_pp.c)
    compiler_preprocess_file(SRC file.c DST file_pp.c
                             DEFINES USE_LIB INCLUDES include/lib)

  Run the preprocessor on a file and save the output to another file. Optionally
  provide defines and include paths to the preprocessor.

  Inputs:

  ``SRC``
    Name of the source file to preprocess.

  ``DST``
    Where to write the preprocessed output.

  ``DEFINES`` (multi, optional)
    Definitions for the preprocessor.

  ``INCLUDES`` (multi, optional)
    Include paths for the preprocessor.

#]===]
function(compiler_preprocess_file)
	set(_OPTIONS_ARGS)
	set(_ONE_VALUE_ARGS SRC DST)
	set(_MULTI_VALUE_ARGS DEFINES INCLUDES)
	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})

	check_args(compiler_preprocess_file SRC DST)

	set(_flags "")
	if(_MY_PARAMS_DEFINES)
		list(TRANSFORM _MY_PARAMS_DEFINES PREPEND -D)
		list(APPEND _flags ${_MY_PARAMS_DEFINES})
	endif()
	if(_MY_PARAMS_INCLUDES)
		list(TRANSFORM _MY_PARAMS_INCLUDES PREPEND -I)
		list(APPEND _flags ${_MY_PARAMS_INCLUDES})
	endif()

	add_custom_command(
		DEPENDS ${_MY_PARAMS_SRC} OUTPUT ${_MY_PARAMS_DST}
		COMMAND ${CMAKE_C_COMPILER} -E -P -x assembler-with-cpp ${_flags}
				${_MY_PARAMS_SRC} -o ${_MY_PARAMS_DST}
	)
endfunction()

#[===[.rst:
.. cmake:command:: compiler_set_linker_script

  .. code-block:: cmake

    compiler_set_linker_script(TARGET foo FILE foo.ld.S)
    compiler_set_linker_script(TARGET foo FILE foo.ld.S DEF USE_LIB INC include/lib)

  Set linker script for a target. The function adds an LDFLAG using the
  toolchain specific syntax to the TARGET_linker_script group, which is applied
  onto the target by the caller function. FILE will be preprocessed, optionally
  defines and/or includes can be provided using DEF/INC arguments.

  Inputs:

  ``TARGET``
    Name of the target.

  ``FILE``
    Linker script file for the target.

  ``DEF`` (multi, optional)
    Defines for the linker script preprocessor.

  ``INC`` (multi, optional)
    Include paths for the linker script preprocessor.

#]===]
function(compiler_set_linker_script)
	set(_OPTIONS_ARGS)
	set(_ONE_VALUE_ARGS TARGET FILE)
	set(_MULTI_VALUE_ARGS DEF INC)
	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})

	check_args(compiler_set_linker_script TARGET FILE)

	get_filename_component(_src "${_MY_PARAMS_FILE}" ABSOLUTE)
	get_filename_component(_src_ext "${_MY_PARAMS_FILE}" EXT)
	set(_dst "${CMAKE_BINARY_DIR}/${_MY_PARAMS_TARGET}.ld")

	if(NOT ("${_src_ext}" STREQUAL ".ld" OR "${_src_ext}" STREQUAL ".ld.S"))
		message(WARNING "compiler_set_linker_script(): extension mismatch '${_src}'")
	endif()

	compiler_preprocess_file(
		SRC ${_src}
		DST ${_dst}
		DEFINES ${_MY_PARAMS_DEF} __LINKER__
		INCLUDES ${_MY_PARAMS_INC}
	)

	add_custom_target("${_MY_PARAMS_TARGET}_ld" DEPENDS "${_dst}")
	add_dependencies("${_MY_PARAMS_TARGET}" "${_MY_PARAMS_TARGET}_ld")

	group_add(NAME "${_MY_PARAMS_TARGET}_linker_script" TYPE CONFIG KEY "LINK_DEPENDS" VAL "${_dst}")
	group_add(NAME "${_MY_PARAMS_TARGET}_linker_script" TYPE LDFLAG KEY "-Wl,--script" VAL "${_dst}")
endfunction()

#[===[.rst:
.. cmake:command:: compiler_generate_binary_output

  .. code-block:: cmake

    compiler_generate_binary_output(TARGET foo)

  Generate binary output for the target. The function converts the output
  executable into bin file using toolchain specific syntax.

  Inputs:

  ``TARGET``
    Name of the target.

#]===]
function(compiler_generate_binary_output TARGET)
	add_custom_command(
		TARGET ${TARGET} POST_BUILD
		COMMAND ${CMAKE_OBJCOPY} -O binary
				$<TARGET_FILE:${TARGET}>
				$<TARGET_FILE_DIR:${TARGET}>/${TARGET}.bin)
endfunction()