1# SPDX-License-Identifier: Apache-2.0 2# 3# Copyright (c) 2021, Nordic Semiconductor ASA 4 5# Zephyr Kernel CMake module. 6# 7# This is the main Zephyr Kernel CMake module which is responsible for creation 8# of Zephyr libraries and the Zephyr executable. 9# 10# This CMake module creates 'project(Zephyr-Kernel)' 11# 12# It defines properties to use while configuring libraries to be built as well 13# as using add_subdirectory() to add the main <ZEPHYR_BASE>/CMakeLists.txt file. 14# 15# Outcome: 16# - Zephyr build system. 17# - Zephyr project 18# 19# Important libraries: 20# - app: This is the main application library where the application can add 21# source files that must be included when building Zephyr 22 23include_guard(GLOBAL) 24 25find_package(TargetTools) 26find_package(ScaTools) 27 28# As this module is not intended for direct loading, but should be loaded through 29# find_package(Zephyr) then it won't be loading any Zephyr CMake modules by itself. 30 31define_property(GLOBAL PROPERTY ZEPHYR_LIBS 32 BRIEF_DOCS "Global list of all Zephyr CMake libs that should be linked in" 33 FULL_DOCS "Global list of all Zephyr CMake libs that should be linked in. 34zephyr_library() appends libs to this list.") 35set_property(GLOBAL PROPERTY ZEPHYR_LIBS "") 36 37define_property(GLOBAL PROPERTY ZEPHYR_INTERFACE_LIBS 38 BRIEF_DOCS "Global list of all Zephyr interface libs that should be linked in." 39 FULL_DOCS "Global list of all Zephyr interface libs that should be linked in. 40zephyr_interface_library_named() appends libs to this list.") 41set_property(GLOBAL PROPERTY ZEPHYR_INTERFACE_LIBS "") 42 43define_property(GLOBAL PROPERTY GENERATED_APP_SOURCE_FILES 44 BRIEF_DOCS "Source files that are generated after Zephyr has been linked once." 45 FULL_DOCS "\ 46Source files that are generated after Zephyr has been linked once.\ 47May include dev_handles.c etc." 48 ) 49set_property(GLOBAL PROPERTY GENERATED_APP_SOURCE_FILES "") 50 51define_property(GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES 52 BRIEF_DOCS "Object files that are generated after symbol addresses are fixed." 53 FULL_DOCS "\ 54Object files that are generated after symbol addresses are fixed.\ 55May include mmu tables, etc." 56 ) 57set_property(GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES "") 58 59define_property(GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES 60 BRIEF_DOCS "Source files that are generated after symbol addresses are fixed." 61 FULL_DOCS "\ 62Source files that are generated after symbol addresses are fixed.\ 63May include isr_tables.c etc." 64 ) 65set_property(GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES "") 66 67add_custom_target(code_data_relocation_target) 68 69# The zephyr/runners.yaml file in the build directory is used to 70# configure the scripts/west_commands/runners Python package used 71# by 'west flash', 'west debug', etc. 72# 73# This is a helper target for setting property:value pairs related to 74# this file: 75# 76# Property Description 77# -------------- -------------------------------------------------- 78# bin_file "zephyr.bin" file for flashing 79# hex_file "zephyr.hex" file for flashing 80# elf_file "zephyr.elf" file for flashing or debugging 81# mot_file "zephyr.mot" file for flashing 82# yaml_contents generated contents of runners.yaml 83# 84# Note: there are quotes around "zephyr.bin" etc. because the actual 85# paths can be changed, e.g. to flash signed versions of these files 86# for consumption by bootloaders such as MCUboot. 87# 88# See cmake/flash/CMakeLists.txt for more details. 89add_custom_target(runners_yaml_props_target) 90 91# CMake's 'project' concept has proven to not be very useful for Zephyr 92# due in part to how Zephyr is organized and in part to it not fitting well 93# with cross compilation. 94# Zephyr therefore tries to rely as little as possible on project() 95# and its associated variables, e.g. PROJECT_SOURCE_DIR. 96# It is recommended to always use ZEPHYR_BASE instead of PROJECT_SOURCE_DIR 97# when trying to reference ENV${ZEPHYR_BASE}. 98 99# Note any later project() resets PROJECT_SOURCE_DIR 100file(TO_CMAKE_PATH "${ZEPHYR_BASE}" PROJECT_SOURCE_DIR) 101 102set(ZEPHYR_BINARY_DIR ${PROJECT_BINARY_DIR}) 103 104if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) 105 message(FATAL_ERROR "Source directory equals build directory.\ 106 In-source builds are not supported.\ 107 Please specify a build directory, e.g. cmake -Bbuild -H.") 108endif() 109 110add_custom_target( 111 pristine 112 COMMAND ${CMAKE_COMMAND} -DBINARY_DIR=${APPLICATION_BINARY_DIR} 113 -DSOURCE_DIR=${APPLICATION_SOURCE_DIR} 114 -P ${ZEPHYR_BASE}/cmake/pristine.cmake 115 # Equivalent to rm -rf build/* 116 ) 117 118# Dummy add to generate files. 119zephyr_linker_sources(SECTIONS) 120 121# For the gen_app_partitions.py to work correctly, we must ensure that 122# all targets exports their compile commands to fetch object files. 123# We enable it unconditionally, as this is also useful for several IDEs 124set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE CACHE BOOL 125 "Export CMake compile commands. Used by gen_app_partitions.py script" 126 FORCE 127) 128 129project(Zephyr-Kernel VERSION ${PROJECT_VERSION}) 130 131# Add .S file extension suffix into CMAKE_ASM_SOURCE_FILE_EXTENSIONS, 132# because clang from OneApi can't recognize them as asm files on 133# windows now. 134list(APPEND CMAKE_ASM_SOURCE_FILE_EXTENSIONS "S") 135enable_language(ASM) 136 137# The setup / configuration of the toolchain itself and the configuration of 138# supported compilation flags are now split, as this allows to use the toolchain 139# for generic purposes, for example DTS, and then test the toolchain for 140# supported flags at stage two. 141# Testing the toolchain flags requires the enable_language() to have been called in CMake. 142 143# Verify that the toolchain can compile a dummy file, if it is not we 144# won't be able to test for compatibility with certain C flags. 145zephyr_check_compiler_flag(C "" toolchain_is_ok) 146set(log_file "CMakeConfigureLog.yaml") 147if(CMAKE_VERSION VERSION_LESS "3.26.0") 148 set(log_file "CMakeError.log") 149endif() 150assert(toolchain_is_ok "The toolchain is unable to build a dummy C file.\ 151 Move ${USER_CACHE_DIR}, re-run and look at ${log_file}") 152 153include(${ZEPHYR_BASE}/cmake/target_toolchain_flags.cmake) 154 155# 'project' sets PROJECT_BINARY_DIR to ${CMAKE_CURRENT_BINARY_DIR}, 156# but for legacy reasons we need it to be set to 157# ${CMAKE_CURRENT_BINARY_DIR}/zephyr 158set(PROJECT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/zephyr) 159set(PROJECT_SOURCE_DIR ${ZEPHYR_BASE}) 160 161set(KERNEL_NAME ${CONFIG_KERNEL_BIN_NAME}) 162 163set(KERNEL_ELF_NAME ${KERNEL_NAME}.elf) 164set(KERNEL_BIN_NAME ${KERNEL_NAME}.bin) 165set(KERNEL_HEX_NAME ${KERNEL_NAME}.hex) 166set(KERNEL_UF2_NAME ${KERNEL_NAME}.uf2) 167set(KERNEL_MAP_NAME ${KERNEL_NAME}.map) 168set(KERNEL_LST_NAME ${KERNEL_NAME}.lst) 169set(KERNEL_S19_NAME ${KERNEL_NAME}.s19) 170set(KERNEL_EXE_NAME ${KERNEL_NAME}.exe) 171set(KERNEL_STAT_NAME ${KERNEL_NAME}.stat) 172set(KERNEL_STRIP_NAME ${KERNEL_NAME}.strip) 173set(KERNEL_META_NAME ${KERNEL_NAME}.meta) 174set(KERNEL_MOT_NAME ${KERNEL_NAME}.mot) 175set(KERNEL_SYMBOLS_NAME ${KERNEL_NAME}.symbols) 176 177# Enable dynamic library support when required by LLEXT. 178if(CONFIG_LLEXT AND CONFIG_LLEXT_TYPE_ELF_SHAREDLIB) 179 set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE) 180endif() 181 182foreach(dir ${BOARD_DIRECTORIES}) 183 include(${dir}/board.cmake OPTIONAL) 184endforeach() 185 186# If we are using a suitable ethernet driver inside qemu, then these options 187# must be set, otherwise a zephyr instance cannot receive any network packets. 188# The Qemu supported ethernet driver should define CONFIG_ETH_NIC_MODEL 189# string that tells what nic model Qemu should use. 190if(CONFIG_QEMU_TARGET) 191 if ((CONFIG_NET_QEMU_ETHERNET OR CONFIG_NET_QEMU_USER) AND NOT CONFIG_ETH_NIC_MODEL) 192 message(FATAL_ERROR " 193 No Qemu ethernet driver configured! 194 Enable Qemu supported ethernet driver like e1000 at drivers/ethernet" 195 ) 196 elseif(CONFIG_NET_QEMU_ETHERNET) 197 if(CONFIG_ETH_QEMU_EXTRA_ARGS) 198 set(NET_QEMU_ETH_EXTRA_ARGS ",${CONFIG_ETH_QEMU_EXTRA_ARGS}") 199 endif() 200 list(APPEND QEMU_FLAGS_${ARCH} 201 -nic tap,model=${CONFIG_ETH_NIC_MODEL},script=no,downscript=no,ifname=${CONFIG_ETH_QEMU_IFACE_NAME}${NET_QEMU_ETH_EXTRA_ARGS} 202 ) 203 elseif(CONFIG_NET_QEMU_USER) 204 list(APPEND QEMU_FLAGS_${ARCH} 205 -nic user,model=${CONFIG_ETH_NIC_MODEL},${CONFIG_NET_QEMU_USER_EXTRA_ARGS} 206 ) 207 else() 208 list(APPEND QEMU_FLAGS_${ARCH} 209 -net none 210 ) 211 endif() 212endif() 213 214# General purpose Zephyr target. 215# This target can be used for custom zephyr settings that needs to be used elsewhere in the build system 216# 217# Currently used properties: 218# - COMPILES_OPTIONS: Used by application memory partition feature 219add_custom_target(zephyr_property_target) 220 221# "app" is a CMake library containing all the application code and is 222# modified by the entry point ${APPLICATION_SOURCE_DIR}/CMakeLists.txt 223# that was specified when cmake was called. 224zephyr_library_named(app) 225set_property(TARGET app PROPERTY ARCHIVE_OUTPUT_DIRECTORY app) 226 227add_subdirectory(${ZEPHYR_BASE} ${__build_dir}) 228 229# Link 'app' with the Zephyr interface libraries. 230# 231# NB: This must be done here because 'app' can only be modified in the 232# CMakeLists.txt file that created it. And it must be 233# done after 'add_subdirectory(${ZEPHYR_BASE} ${__build_dir})' 234# because interface libraries are defined while processing that 235# subdirectory. 236get_property(ZEPHYR_INTERFACE_LIBS_PROPERTY GLOBAL PROPERTY ZEPHYR_INTERFACE_LIBS) 237foreach(boilerplate_lib ${ZEPHYR_INTERFACE_LIBS_PROPERTY}) 238 # Linking 'app' with 'boilerplate_lib' causes 'app' to inherit the INTERFACE 239 # properties of 'boilerplate_lib'. The most common property is 'include 240 # directories', but it is also possible to have defines and compiler 241 # flags in the interface of a library. 242 # 243 string(TOUPPER ${boilerplate_lib} boilerplate_lib_upper_case) # Support lowercase lib names 244 target_link_libraries_ifdef( 245 CONFIG_APP_LINK_WITH_${boilerplate_lib_upper_case} 246 app 247 PUBLIC 248 ${boilerplate_lib} 249 ) 250endforeach() 251 252if("${CMAKE_EXTRA_GENERATOR}" STREQUAL "Eclipse CDT4") 253 # Call the amendment function before .project and .cproject generation 254 # C and CXX includes, defines in .cproject without __cplusplus 255 # with project includes and defines 256 include(${ZEPHYR_BASE}/cmake/ide/eclipse_cdt4_generator_amendment.cmake) 257 eclipse_cdt4_generator_amendment(1) 258endif() 259