blob: c773613576edaf238629ef117402d8d70842fb97 [file] [log] [blame]
Gyorgy Szing5e429cb2019-12-03 20:39:55 +01001#-------------------------------------------------------------------------------
2# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6#-------------------------------------------------------------------------------
7
8#[===[.rst:
9Compiler abstraction for GCC
10----------------------------
11#]===]
12
13include_guard(DIRECTORY)
14
15if(NOT DEFINED CROSS_COMPILE AND NOT DEFINED ENV{CROSS_COMPILE})
16 message(FATAL_ERROR "'CROSS_COMPILE' is not defined.")
17endif()
18
19set(CROSS_COMPILE $ENV{CROSS_COMPILE} CACHE STRING "Prefix of the cross-compiler commands")
20
21find_program(_cross_compile_gcc NAMES ${CROSS_COMPILE}gcc ${CROSS_COMPILE}gcc.exe REQUIRED)
22set(CMAKE_C_COMPILER ${_cross_compile_gcc})
23
24#Official solution to disable compiler checks
25set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
26
27#[===[.rst:
28.. cmake:command:: compiler_preprocess_file
29
30 .. code-block:: cmake
31
32 compiler_preprocess_file(SRC file.c DST file_pp.c)
33 compiler_preprocess_file(SRC file.c DST file_pp.c
34 DEFINES USE_LIB INCLUDES include/lib)
35
36 Run the preprocessor on a file and save the output to another file. Optionally
37 provide defines and include paths to the preprocessor.
38
39 Inputs:
40
41 ``SRC``
42 Name of the source file to preprocess.
43
44 ``DST``
45 Where to write the preprocessed output.
46
47 ``DEFINES`` (multi, optional)
48 Definitions for the preprocessor.
49
50 ``INCLUDES`` (multi, optional)
51 Include paths for the preprocessor.
52
53#]===]
54function(compiler_preprocess_file)
55 set(_OPTIONS_ARGS)
56 set(_ONE_VALUE_ARGS SRC DST)
57 set(_MULTI_VALUE_ARGS DEFINES INCLUDES)
58 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
59
60 check_args(compiler_preprocess_file SRC DST)
61
62 set(_flags "")
63 if(_MY_PARAMS_DEFINES)
64 list(TRANSFORM _MY_PARAMS_DEFINES PREPEND -D)
65 list(APPEND _flags ${_MY_PARAMS_DEFINES})
66 endif()
67 if(_MY_PARAMS_INCLUDES)
68 list(TRANSFORM _MY_PARAMS_INCLUDES PREPEND -I)
69 list(APPEND _flags ${_MY_PARAMS_INCLUDES})
70 endif()
71
72 add_custom_command(
73 DEPENDS ${_MY_PARAMS_SRC} OUTPUT ${_MY_PARAMS_DST}
74 COMMAND ${CMAKE_C_COMPILER} -E -P -x assembler-with-cpp ${_flags}
75 ${_MY_PARAMS_SRC} -o ${_MY_PARAMS_DST}
76 )
77endfunction()
78
79#[===[.rst:
80.. cmake:command:: compiler_set_linker_script
81
82 .. code-block:: cmake
83
84 compiler_set_linker_script(TARGET foo FILE foo.ld.S)
85 compiler_set_linker_script(TARGET foo FILE foo.ld.S DEF USE_LIB INC include/lib)
86
87 Set linker script for a target. The function adds an LDFLAG using the
88 toolchain specific syntax to the TARGET_linker_script group, which is applied
89 onto the target by the caller function. FILE will be preprocessed, optionally
90 defines and/or includes can be provided using DEF/INC arguments.
91
92 Inputs:
93
94 ``TARGET``
95 Name of the target.
96
97 ``FILE``
98 Linker script file for the target.
99
100 ``DEF`` (multi, optional)
101 Defines for the linker script preprocessor.
102
103 ``INC`` (multi, optional)
104 Include paths for the linker script preprocessor.
105
106#]===]
107function(compiler_set_linker_script)
108 set(_OPTIONS_ARGS)
109 set(_ONE_VALUE_ARGS TARGET FILE)
110 set(_MULTI_VALUE_ARGS DEF INC)
111 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
112
113 check_args(compiler_set_linker_script TARGET FILE)
114
115 get_filename_component(_src "${_MY_PARAMS_FILE}" ABSOLUTE)
116 get_filename_component(_src_ext "${_MY_PARAMS_FILE}" EXT)
117 set(_dst "${CMAKE_BINARY_DIR}/${_MY_PARAMS_TARGET}.ld")
118
119 if(NOT ("${_src_ext}" STREQUAL ".ld" OR "${_src_ext}" STREQUAL ".ld.S"))
120 message(WARNING "compiler_set_linker_script(): extension mismatch '${_src}'")
121 endif()
122
123 compiler_preprocess_file(
124 SRC ${_src}
125 DST ${_dst}
126 DEFINES ${_MY_PARAMS_DEF} __LINKER__
127 INCLUDES ${_MY_PARAMS_INC}
128 )
129
130 add_custom_target("${_MY_PARAMS_TARGET}_ld" DEPENDS "${_dst}")
131 add_dependencies("${_MY_PARAMS_TARGET}" "${_MY_PARAMS_TARGET}_ld")
132
133 group_add(NAME "${_MY_PARAMS_TARGET}_linker_script" TYPE CONFIG KEY "LINK_DEPENDS" VAL "${_dst}")
134 group_add(NAME "${_MY_PARAMS_TARGET}_linker_script" TYPE LDFLAG KEY "-Wl,--script" VAL "${_dst}")
135endfunction()
136
137#[===[.rst:
138.. cmake:command:: compiler_generate_binary_output
139
140 .. code-block:: cmake
141
142 compiler_generate_binary_output(TARGET foo)
143
144 Generate binary output for the target. The function converts the output
145 executable into bin file using toolchain specific syntax.
146
147 Inputs:
148
149 ``TARGET``
150 Name of the target.
151
152#]===]
153function(compiler_generate_binary_output TARGET)
154 add_custom_command(
155 TARGET ${TARGET} POST_BUILD
156 COMMAND ${CMAKE_OBJCOPY} -O binary
157 $<TARGET_FILE:${TARGET}>
158 $<TARGET_FILE_DIR:${TARGET}>/${TARGET}.bin)
159endfunction()