1#
2# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3#
4# SPDX-License-Identifier: GPL-2.0-only
5#
6
7cmake_minimum_required(VERSION 3.7.2)
8
9set(CMAKE_SYSTEM_NAME Generic)
10# For a generic system this is unused, so define it to something that will be
11# obvious if someone accidentally uses it
12set(CMAKE_SYSTEM_PROCESSOR seL4CPU)
13
14set(CMAKE_SYSROOT "${CMAKE_BINARY_DIR}")
15
16# When this file is passed to configure_file in cmake, these variables get set to
17# the kernel platform configuration.
18set(sel4_arch @KernelSel4Arch@)
19set(arch @KernelArch@)
20set(mode @KernelWordSize@)
21set(cross_prefix @cross_prefix@)
22
23# If this file is used without templating, then cross_prefix will
24# have an invalid value and should only be assigned to CROSS_COMPILER_PREFIX
25# if it has been set to something different.
26# We need to build the test string dynamically otherwise the templating would
27# overwrite it.
28set(cross_prefix_test @cross_prefix)
29string(APPEND cross_prefix_test @)
30if((NOT "${cross_prefix}" STREQUAL "${cross_prefix_test}") AND (NOT "${cross_prefix}" STREQUAL ""))
31    set(CROSS_COMPILER_PREFIX ${cross_prefix})
32endif()
33
34# This function hunts for an extant `gcc` with one of the candidate prefixes
35# specified in `ARGN`, allowing us to try different target triple prefixes for
36# cross-compilers built in various ways.
37function(FindPrefixedGCC out_var)
38    set("${out_var}" "PrefixedGCC-NOTFOUND")
39    foreach(prefix ${ARGN})
40        set("test_var" "_GCC_${prefix}")
41        find_program("${test_var}" "${prefix}gcc")
42        if(${test_var})
43            message(STATUS "Found GCC with prefix ${prefix}")
44            set("${out_var}" "${prefix}")
45            break()
46        endif()
47    endforeach()
48    if(${out_var})
49        set("${out_var}" "${${out_var}}" PARENT_SCOPE)
50    else()
51        message(FATAL_ERROR "Unable to find valid cross-compiling GCC")
52    endif()
53endfunction(FindPrefixedGCC)
54
55if("${CROSS_COMPILER_PREFIX}" STREQUAL "")
56    if(("${arch}" STREQUAL "arm") OR ("${arch}" STREQUAL "x86") OR ("${arch}" STREQUAL "riscv"))
57        if(${sel4_arch} STREQUAL "aarch32" OR ${sel4_arch} STREQUAL "arm_hyp")
58            FindPrefixedGCC(CROSS_COMPILER_PREFIX "arm-linux-gnueabi-" "arm-linux-gnu-")
59        elseif(${sel4_arch} STREQUAL "aarch64")
60            set(CROSS_COMPILER_PREFIX "aarch64-linux-gnu-")
61        elseif(${arch} STREQUAL "riscv")
62            FindPrefixedGCC(
63                CROSS_COMPILER_PREFIX
64                "riscv64-unknown-linux-gnu-"
65                "riscv64-unknown-elf-"
66                "riscv64-elf-"
67            )
68        endif()
69    else()
70        # For backwards compatibility reasons we allow this file to work without templating.
71        # If initialised with -DCMAKE_TOOLCHAIN_FILE="$SCRIPT_PATH/gcc.cmake" this script
72        # understood the following arguments: ARM, AARCH32, AARCH32HF, AARCH64, RISCV32, RISCV64, APPLE
73        if(AARCH32 OR ARM)
74            FindPrefixedGCC(CROSS_COMPILER_PREFIX "arm-linux-gnueabi-" "arm-linux-gnu-")
75            if(ARM)
76                message("ARM flag is deprecated, please use AARCH32")
77            endif()
78        elseif(AARCH64)
79            set(CROSS_COMPILER_PREFIX "aarch64-linux-gnu-")
80        elseif(RISCV32 OR RISCV64)
81            FindPrefixedGCC(
82                CROSS_COMPILER_PREFIX
83                "riscv64-unknown-linux-gnu-"
84                "riscv64-unknown-elf-"
85                "riscv64-elf-"
86            )
87        endif()
88    endif()
89    if(AARCH32HF)
90        FindPrefixedGCC(
91            CROSS_COMPILER_PREFIX
92            "arm-linux-gnueabihf-"
93            "arm-linux-gnu-" # Later checks should confirm this has `hardfp`
94        )
95    endif()
96
97    if("${CROSS_COMPILER_PREFIX}" STREQUAL "")
98        # If we haven't set a target above we assume x86_64/ia32 target
99        if(APPLE)
100            # APPLE is a CMake variable that evaluates to True on a Mac OSX system
101            set(CROSS_COMPILER_PREFIX "x86_64-unknown-linux-gnu-")
102        endif()
103    endif()
104endif()
105
106set(CMAKE_C_COMPILER ${CROSS_COMPILER_PREFIX}gcc)
107set(CMAKE_ASM_COMPILER ${CROSS_COMPILER_PREFIX}gcc)
108set(CMAKE_CXX_COMPILER ${CROSS_COMPILER_PREFIX}g++)
109
110set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
111set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
112set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
113set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
114
115set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
116
117mark_as_advanced(FORCE CMAKE_TOOLCHAIN_FILE)
118
119# Invoke compiler via ccache. This has no effect if ccache cannot be found.
120# Projects can override this effect by resetting the RULE_LAUNCH_COMPILE and
121# RULE_LAUNCH_LINK properties.
122find_program(CCACHE ccache)
123if(NOT ("${CCACHE}" STREQUAL CCACHE-NOTFOUND))
124    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
125    set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE})
126endif()
127mark_as_advanced(CCACHE)
128
129# GCC color options:
130# Ninja and ccache cause gcc to not emit colored output when -fdiagnostics-color=auto.
131# We upgrade this to -fdiagnostics-color=always if FORCE_COLORED_OUTPUT is set
132# We default FORCE_COLORED_OUTPUT=ON if GCC_COLORS is set in the environment
133# otherwise FORCE_COLORED_OUTPUT is left off.
134if($ENV{GCC_COLORS})
135    set(coloured_output ON)
136else()
137    set(coloured_output OFF)
138endif()
139option(FORCE_COLORED_OUTPUT "Always produce ANSI-colored output." ${coloured_output})
140mark_as_advanced(FORCE_COLORED_OUTPUT)
141if(${FORCE_COLORED_OUTPUT})
142    include_guard(GLOBAL)
143    add_compile_options(-fdiagnostics-color=always)
144endif()
145