blob: cb2c9126519ee6b802a0367a6528dec13de3d948 [file]
#
# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
#
# SPDX-License-Identifier: BSD-2-Clause
#
cmake_minimum_required(VERSION 3.7.2)
include_guard(GLOBAL)
macro(add_default_compilation_options)
# Setup base flags as defined by the kernel before including the rest
include(${KERNEL_FLAGS_PATH})
if(("${CMAKE_BUILD_TYPE}" STREQUAL "Release") OR ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel"))
option(UserLinkerGCSections "Perform dead code and data removal
Build user level with -ffunction-sections and -fdata-sections and
link with --gc-sections. The first two options place each function
and data in a different section such that --gc-sections is able
to effectively discard sections that are unused after a reachability
analysis. This does not interact well with debug symbols generated
by -g and can in some cases result in larger object files and binaries" ON)
if(UserLinkerGCSections)
add_compile_options(-ffunction-sections -fdata-sections)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections ")
endif()
endif()
mark_as_advanced(UserLinkerGCSections)
add_compile_options(
-nostdinc
-fno-pic
-fno-pie
-fno-stack-protector
-fno-asynchronous-unwind-tables
-ftls-model=local-exec
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++")
set(CMAKE_C_STANDARD 11)
set(LinkPageSize "0x1000" CACHE STRING "Page size to be used for linker")
mark_as_advanced(LinkPageSize)
set(
CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -static -nostdlib -z max-page-size=${LinkPageSize}"
)
if(KernelArchX86)
add_compile_options(-mtls-direct-seg-refs)
endif()
if(KernelSel4ArchAarch32)
add_compile_options(-mtp=soft)
endif()
# Don't allow unaligned data store/load instructions as this will cause an alignment
# fault on any seL4 memory regions that are uncached as the mapping attributes the kernel
# uses causes alignment checks to be enabled.
if(KernelSel4ArchAarch64)
add_compile_options(-mstrict-align)
if(NOT CMAKE_C_COMPILER_VERSION)
message(FATAL_ERROR "CMAKE_C_COMPILER_VERSION is not set")
endif()
# special handling for GCC 10 and above
if(
(CMAKE_C_COMPILER_ID STREQUAL "GNU")
AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0.0")
)
add_compile_options(-mno-outline-atomics)
endif()
elseif(KernelSel4ArchAarch32)
add_compile_options(-mno-unaligned-access)
endif()
endmacro()
macro(gcc_print_file_name var file)
separate_arguments(c_arguments UNIX_COMMAND "${CMAKE_C_FLAGS}")
# Append the target flag to the arguments if we are using clang so the
# correct crt files are found
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
list(APPEND c_arguments "${CMAKE_C_COMPILE_OPTIONS_TARGET}${CMAKE_C_COMPILER_TARGET}")
endif()
execute_process(
COMMAND ${CMAKE_C_COMPILER} ${c_arguments} -print-file-name=${file}
OUTPUT_VARIABLE ${var}
ERROR_VARIABLE IgnoreErrorOutput
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endmacro()
macro(find_libgcc_files)
# find the compilers crtbegin and crtend files
gcc_print_file_name(CRTBeginFile crtbegin.o)
gcc_print_file_name(CRTEndFile crtend.o)
gcc_print_file_name(libgcc_eh libgcc_eh.a)
set(libgcc "-lgcc")
if(NOT "${libgcc_eh}" STREQUAL "libgcc_eh.a")
set(libgcc "${libgcc} -lgcc_eh")
endif()
endmacro()
# Call check_c_source_runs but set the cache variables
# that cause the generated executable to not be run
# on cross_compilation targets.
macro(check_c_source_runs_cross_compile program var)
# Clear the variable from the cache to force testing it
# each time CMake is run.
unset(${var} CACHE)
# Set internal variables to avoid running the executable.
set(${var}_EXITCODE 0 CACHE INTERNAL "")
set(${var}_EXITCODE__TRYRUN_OUTPUT "" CACHE INTERNAL "")
# Save the current CMAKE_REQUIRED_QUIET setting in order
# to set it to ON to suppress any output before restoring
# it to its old value.
set(${var}_save ${CMAKE_REQUIRED_QUIET})
set(CMAKE_REQUIRED_QUIET ON)
check_c_source_runs(${program} ${var})
set(CMAKE_REQUIRED_QUIET ${${var}_save})
endmacro()
macro(add_fpu_compilation_options)
# We want to check what we can set the -mfloat-abi to on arm and if that matches what is requested
if(KernelSel4ArchAarch64)
if(NOT KernelHaveFPU)
add_compile_options(-mgeneral-regs-only)
endif()
elseif(KernelArchARM)
find_libgcc_files()
include(CheckCSourceRuns)
# Set the link libraries to use our crt and libgcc files.
# This picks up inconsistencies in floating point ABIs.
set(CMAKE_REQUIRED_LIBRARIES ${CRTBeginFile} ${libgcc} ${CRTEndFile})
set(test_program "void main(void){}")
if(KernelHaveFPU)
set(CMAKE_REQUIRED_FLAGS "-mfloat-abi=hard")
check_c_source_runs_cross_compile(${test_program} HARD_FLOAT)
if(NOT HARD_FLOAT)
set(CMAKE_REQUIRED_FLAGS "-mfloat-abi=softfp")
check_c_source_runs_cross_compile(${test_program} SOFTFP_FLOAT)
if(NOT SOFTFP_FLOAT)
message(
WARNING "Kernel supports hardware floating point but toolchain does not"
)
add_compile_options(-mfloat-abi=soft)
else()
add_compile_options(-mfloat-abi=softfp)
endif()
else()
add_compile_options(-mfloat-abi=hard)
endif()
else()
set(CMAKE_REQUIRED_FLAGS "-mfloat-abi=soft")
check_c_source_runs_cross_compile(${test_program} SOFT_FLOAT)
if(NOT SOFT_FLOAT)
message(
SEND_ERROR
"Kernel does not support hardware floating point but toolchain cannot build software floating point"
)
else()
add_compile_options(-mfloat-abi=soft)
endif()
endif()
endif()
endmacro()