blob: c773613576edaf238629ef117402d8d70842fb97 [file] [log] [blame]
#-------------------------------------------------------------------------------
# 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()