1#
2# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3#
4# SPDX-License-Identifier: BSD-2-Clause
5#
6
7cmake_minimum_required(VERSION 3.7.2)
8include_guard(GLOBAL)
9
10macro(add_default_compilation_options)
11    # Setup base flags as defined by the kernel before including the rest
12    include(${KERNEL_FLAGS_PATH})
13
14    if(("${CMAKE_BUILD_TYPE}" STREQUAL "Release") OR ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel"))
15        option(UserLinkerGCSections "Perform dead code and data removal
16            Build user level with -ffunction-sections and -fdata-sections and
17            link with --gc-sections. The first two options place each function
18            and data in a different section such that --gc-sections is able
19            to effectively discard sections that are unused after a reachability
20            analysis. This does not interact well with debug symbols generated
21            by -g and can in some cases result in larger object files and binaries" ON)
22
23        if(UserLinkerGCSections)
24            add_compile_options(-ffunction-sections -fdata-sections)
25            set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections ")
26        endif()
27    endif()
28    mark_as_advanced(UserLinkerGCSections)
29
30    add_compile_options(
31        -nostdinc
32        -fno-pic
33        -fno-pie
34        -fno-stack-protector
35        -fno-asynchronous-unwind-tables
36        -ftls-model=local-exec
37    )
38    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++")
39    set(CMAKE_C_STANDARD 11)
40    set(LinkPageSize "0x1000" CACHE STRING "Page size to be used for linker")
41    mark_as_advanced(LinkPageSize)
42    set(
43        CMAKE_EXE_LINKER_FLAGS
44        "${CMAKE_EXE_LINKER_FLAGS} -static -nostdlib -z max-page-size=${LinkPageSize}"
45    )
46
47    if(KernelArchX86)
48        add_compile_options(-mtls-direct-seg-refs)
49    endif()
50
51    if(KernelSel4ArchAarch32)
52        add_compile_options(-mtp=soft)
53    endif()
54
55    # Don't allow unaligned data store/load instructions as this will cause an alignment
56    # fault on any seL4 memory regions that are uncached as the mapping attributes the kernel
57    # uses causes alignment checks to be enabled.
58    if(KernelSel4ArchAarch64)
59        add_compile_options(-mstrict-align)
60        if(NOT CMAKE_C_COMPILER_VERSION)
61            message(FATAL_ERROR "CMAKE_C_COMPILER_VERSION is not set")
62        endif()
63        # special handling for GCC 10 and above
64        if(
65            (CMAKE_C_COMPILER_ID STREQUAL "GNU")
66            AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0.0")
67        )
68            add_compile_options(-mno-outline-atomics)
69        endif()
70    elseif(KernelSel4ArchAarch32)
71        add_compile_options(-mno-unaligned-access)
72    endif()
73endmacro()
74
75macro(gcc_print_file_name var file)
76    if(NOT (DEFINED "${var}"))
77        separate_arguments(c_arguments UNIX_COMMAND "${CMAKE_C_FLAGS}")
78        # Append the target flag to the arguments if we are using clang so the
79        # correct crt files are found
80        if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
81            list(APPEND c_arguments "${CMAKE_C_COMPILE_OPTIONS_TARGET}${CMAKE_C_COMPILER_TARGET}")
82        endif()
83        execute_process(
84            COMMAND ${CMAKE_C_COMPILER} ${c_arguments} -print-file-name=${file}
85            OUTPUT_VARIABLE ${var}
86            ERROR_VARIABLE IgnoreErrorOutput
87            OUTPUT_STRIP_TRAILING_WHITESPACE
88        )
89        set("${var}" "${${var}}" CACHE INTERNAL "")
90    endif()
91endmacro()
92
93macro(find_libgcc_files)
94
95    # find the compilers crtbegin and crtend files
96    gcc_print_file_name(CRTBeginFile crtbegin.o)
97    gcc_print_file_name(CRTEndFile crtend.o)
98    gcc_print_file_name(libgcc_eh libgcc_eh.a)
99    set(libgcc "-lgcc")
100    if(NOT "${libgcc_eh}" STREQUAL "libgcc_eh.a")
101        set(libgcc "${libgcc} -lgcc_eh")
102    endif()
103endmacro()
104
105# Call check_c_source_runs but set the cache variables
106# that cause the generated executable to not be run
107# on cross_compilation targets.
108macro(check_c_source_runs_cross_compile program var)
109    set(${var}_EXITCODE 0 CACHE INTERNAL "")
110    set(${var}_EXITCODE__TRYRUN_OUTPUT "" CACHE INTERNAL "")
111    check_c_source_runs(${program} ${var})
112endmacro()
113
114macro(add_fpu_compilation_options)
115    # We want to check what we can set the -mfloat-abi to on arm and if that matches what is requested
116    if(KernelSel4ArchAarch64)
117        if(NOT KernelHaveFPU)
118            add_compile_options(-mgeneral-regs-only)
119        endif()
120    elseif(KernelArchARM)
121        find_libgcc_files()
122        include(CheckCSourceRuns)
123        # Set the link libraries to use our crt and libgcc files.
124        # This picks up inconsistencies in floating point ABIs.
125        set(CMAKE_REQUIRED_LIBRARIES ${CRTBeginFile} ${libgcc} ${CRTEndFile})
126        set(test_program "void main(void){}")
127        if(KernelHaveFPU)
128            set(CMAKE_REQUIRED_FLAGS "-mfloat-abi=hard")
129            check_c_source_runs_cross_compile(${test_program} HARD_FLOAT)
130            if(NOT HARD_FLOAT)
131                set(CMAKE_REQUIRED_FLAGS "-mfloat-abi=softfp")
132                check_c_source_runs_cross_compile(${test_program} SOFTFP_FLOAT)
133                if(NOT SOFTFP_FLOAT)
134                    message(
135                        WARNING "Kernel supports hardware floating point but toolchain does not"
136                    )
137                    add_compile_options(-mfloat-abi=soft)
138                else()
139                    add_compile_options(-mfloat-abi=softfp)
140                endif()
141            else()
142                add_compile_options(-mfloat-abi=hard)
143            endif()
144        else()
145            set(CMAKE_REQUIRED_FLAGS "-mfloat-abi=soft")
146            check_c_source_runs_cross_compile(${test_program} SOFT_FLOAT)
147            if(NOT SOFT_FLOAT)
148                message(
149                    SEND_ERROR
150                        "Kernel does not support hardware floating point but toolchain cannot build software floating point"
151                )
152            else()
153                add_compile_options(-mfloat-abi=soft)
154            endif()
155        endif()
156    endif()
157endmacro()
158