blob: dffda553f1f3c6694186ce14acc8120e3edb4148 [file] [log] [blame]
# This file must be included into the toplevel CMakeLists.txt file of
# Zephyr applications, e.g. zephyr/samples/hello_world/CMakeLists.txt
# must start with the line:
#
# include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
#
# It exists to reduce boilerplate code that Zephyr expects to be in
# application CMakeLists.txt code.
#
# Omitting it is permitted, but doing so incurs a maintenance cost as
# the application must manage upstream changes to this file.
# app is a CMake library containing all the application code and is
# modified by the entry point ${APPLICATION_SOURCE_DIR}/CMakeLists.txt
# that was specified when cmake was called.
# Determine if we are using MSYS.
#
# We don't use project() because it would take some time to rewrite
# the build scripts to be compatible with everything project() does.
execute_process(
COMMAND
uname
OUTPUT_VARIABLE uname_output
)
if(uname_output MATCHES "MSYS")
set(MSYS 1)
endif()
# CMake version 3.8.2 is the only supported version. Version 3.9 is
# not supported because it introduced a warning that we do not wish to
# show to users. Specifically, it displays a warning when an OLD
# policy is used, but we need policy CMP0000 set to OLD to avoid
# copy-pasting cmake_minimum_required across application
# CMakeLists.txt files.
#
# An exception to the above is MSYS, MSYS is allowed to use 3.6.0
# because MSYS does not support 3.8, this will be set back to 3.8 when
# https://github.com/zephyrproject-rtos/zephyr/issues/4687 is
# resolved.
if(MSYS)
cmake_minimum_required(VERSION 3.6.0)
else()
cmake_minimum_required(VERSION 3.8.2)
endif()
cmake_policy(SET CMP0000 OLD)
cmake_policy(SET CMP0002 NEW)
set(APPLICATION_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH "Application Source Directory")
set(APPLICATION_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH "Application Binary Directory")
set(__build_dir ${CMAKE_CURRENT_BINARY_DIR}/zephyr)
set(PROJECT_BINARY_DIR ${__build_dir})
set(PROJECT_SOURCE_DIR $ENV{ZEPHYR_BASE})
set(ZEPHYR_BINARY_DIR ${PROJECT_BINARY_DIR})
set(ZEPHYR_SOURCE_DIR ${PROJECT_SOURCE_DIR})
set(AUTOCONF_H ${__build_dir}/include/generated/autoconf.h)
# Re-configure (Re-execute all CMakeLists.txt code) when autoconf.h changes
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${AUTOCONF_H})
include($ENV{ZEPHYR_BASE}/cmake/extensions.cmake)
find_package(PythonInterp 3.4)
if(NOT ZEPHYR_GCC_VARIANT)
set(ZEPHYR_GCC_VARIANT $ENV{ZEPHYR_GCC_VARIANT})
endif()
set(ZEPHYR_GCC_VARIANT ${ZEPHYR_GCC_VARIANT} CACHE STRING "Zephyr GCC variant")
if(NOT ZEPHYR_GCC_VARIANT)
message(FATAL_ERROR "ZEPHYR_GCC_VARIANT not set")
endif()
if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
message(FATAL_ERROR "Source directory equals build directory.\
In-source builds are not supported.\
Please specify a build directory, e.g. cmake -Bbuild -H.")
endif()
add_custom_target(
pristine
COMMAND ${CMAKE_COMMAND} -P $ENV{ZEPHYR_BASE}/cmake/pristine.cmake
# Equivalent to rm -rf build/*
)
# The BOARD can be set by 3 sources. Through environment variables,
# through the cmake CLI, and through CMakeLists.txt.
#
# CLI has the highest precedence, then comes environment variables,
# and then finally CMakeLists.txt.
#
# A user can ignore all the precedence rules if he simply always uses
# the same source. E.g. always specifies -DBOARD= on the command line,
# always has an environment variable set, or always has a set(BOARD
# foo) line in his CMakeLists.txt and avoids mixing sources.
#
# The selected BOARD can be accessed through the variable 'BOARD'.
# Read out the cached board value if present
get_property(cached_board_value CACHE BOARD PROPERTY VALUE)
# There are actually 4 sources, the three user input sources, and the
# previously used value (CACHED_BOARD). The previously used value has
# precedence, and if we detect that the user is trying to change the
# value we give him a warning about needing to clean the build
# directory to be able to change boards.
set(board_cli_argument ${cached_board_value}) # Either new or old
if(board_cli_argument STREQUAL CACHED_BOARD)
# We already have a CACHED_BOARD so there is no new input on the CLI
unset(board_cli_argument)
endif()
set(board_app_cmake_lists ${BOARD})
if(cached_board_value STREQUAL BOARD)
# The app build scripts did not set a default, The BOARD we are
# reading is the cached value from the CLI
unset(board_app_cmake_lists)
endif()
if(CACHED_BOARD)
# Warn the user if it looks like he is trying to change the board
# without cleaning first
if(board_cli_argument)
if(NOT (CACHED_BOARD STREQUAL board_cli_argument))
message(WARNING "The build directory must be cleaned pristinely when changing boards")
# TODO: Support changing boards without requiring a clean build
endif()
endif()
set(BOARD ${CACHED_BOARD})
elseif(board_cli_argument)
set(BOARD ${board_cli_argument})
elseif(DEFINED ENV{BOARD})
set(BOARD $ENV{BOARD})
elseif(board_app_cmake_lists)
set(BOARD ${board_app_cmake_lists})
else()
message(FATAL_ERROR "BOARD is not being defined on the CMake command-line in the environment or by the app.")
endif()
assert(BOARD "BOARD not set")
message(STATUS "Selected BOARD ${BOARD}")
# Store the selected board in the cache
set(CACHED_BOARD ${BOARD} CACHE STRING "Selected board")
# Use BOARD to search zephyr/boards/** for a _defconfig file,
# e.g. zephyr/boards/arm/96b_carbon_nrf51/96b_carbon_nrf51_defconfig. When
# found, use that path to infer the ARCH we are building for.
find_path(BOARD_DIR NAMES "${BOARD}_defconfig" PATHS $ENV{ZEPHYR_BASE}/boards/*/* NO_DEFAULT_PATH)
assert_with_usage(BOARD_DIR "No board named '${BOARD}' found")
get_filename_component(BOARD_ARCH_DIR ${BOARD_DIR} DIRECTORY)
get_filename_component(ARCH ${BOARD_ARCH_DIR} NAME)
get_filename_component(BOARD_FAMILY ${BOARD_DIR} NAME)
if(CONF_FILE)
# CONF_FILE has either been specified on the cmake CLI or is already
# in the CMakeCache.txt. This has precedence over the environment
# variable CONF_FILE and the default prj.conf
elseif(DEFINED ENV{CONF_FILE})
set(CONF_FILE $ENV{CONF_FILE})
elseif(COMMAND set_conf_file)
set_conf_file()
elseif(EXISTS ${APPLICATION_SOURCE_DIR}/prj_${BOARD}.conf)
set(CONF_FILE ${APPLICATION_SOURCE_DIR}/prj_${BOARD}.conf)
elseif(EXISTS ${APPLICATION_SOURCE_DIR}/prj.conf)
set(CONF_FILE ${APPLICATION_SOURCE_DIR}/prj.conf)
endif()
set(CONF_FILE ${CONF_FILE} CACHE STRING "If desired, you can build the application using\
the configuration settings specified in an alternate .conf file using this parameter. \
These settings will override the settings in the application’s .config file or its default .conf file.\
Multiple files may be listed, e.g. CONF_FILE=\"prj1.conf prj2.conf\"")
# Prevent CMake from testing the toolchain
set(CMAKE_C_COMPILER_FORCED 1)
set(CMAKE_CXX_COMPILER_FORCED 1)
# Determine if the application is in zephyr/tests, if so it is a test
# and must be built differently
string(REGEX MATCH "^$ENV{ZEPHYR_BASE}/tests" match ${APPLICATION_SOURCE_DIR})
if(match)
set(IS_TEST 1)
endif()
include($ENV{ZEPHYR_BASE}/cmake/version.cmake)
include($ENV{ZEPHYR_BASE}/cmake/host-tools.cmake)
include($ENV{ZEPHYR_BASE}/cmake/kconfig.cmake)
include($ENV{ZEPHYR_BASE}/cmake/toolchain.cmake)
# DTS should be run directly after kconfig because CONFIG_ variables
# from kconfig and dts should be available at the same time. But
# running DTS involves running the preprocessor, so we put it behind
# toolchain. Meaning toolchain.cmake is the only component where
# kconfig and dts variables aren't available at the same time.
include($ENV{ZEPHYR_BASE}/dts/dts.cmake)
set(KERNEL_NAME ${CONFIG_KERNEL_BIN_NAME})
set(KERNEL_ELF_NAME ${KERNEL_NAME}.elf)
set(KERNEL_BIN_NAME ${KERNEL_NAME}.bin)
set(KERNEL_HEX_NAME ${KERNEL_NAME}.hex)
set(KERNEL_MAP_NAME ${KERNEL_NAME}.map)
set(KERNEL_LST_NAME ${KERNEL_NAME}.lst)
set(KERNEL_S19_NAME ${KERNEL_NAME}.s19)
set(KERNEL_STAT_NAME ${KERNEL_NAME}.stat)
set(KERNEL_STRIP_NAME ${KERNEL_NAME}.strip)
include(${BOARD_DIR}/board.cmake OPTIONAL)
zephyr_library_named(app)
add_subdirectory($ENV{ZEPHYR_BASE} ${__build_dir})
define_property(GLOBAL PROPERTY ZEPHYR_LIBS
BRIEF_DOCS "Global list of all Zephyr CMake libs that should be linked in"
FULL_DOCS "Global list of all Zephyr CMake libs that should be linked in. zephyr_library() appends libs to this list.")
set_property(GLOBAL PROPERTY ZEPHYR_LIBS "")
define_property(GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES
BRIEF_DOCS "Object files that are generated after Zephyr has been linked once."
FULL_DOCS "\
Object files that are generated after Zephyr has been linked once.\
May include mmu tables, etc."
)
set_property(GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES "")
define_property(GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES
BRIEF_DOCS "Source files that are generated after Zephyr has been linked once."
FULL_DOCS "\
Object files that are generated after Zephyr has been linked once.\
May include isr_tables.c etc."
)
set_property(GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES "")