zephyr/cmake/app/boilerplate.cmake
Marti Bolivar 7a3462de7a scripts: runner: use arguments, not environment vars
The various runners (flash/debug scripts) use environment variables to
take arguments. This is legacy behavior which is not desirable.

Use command line arguments instead.

Note: this leaves more general environment variables with publicly
      documented behavior in place for now, for compatibility, e.g.:

      ZEPHYR_FLASH_OVER_DFU, OPENSDA_FW, ESP_IDF_PATH, PYOCD_DAPARG

For example, when using dfu-util to flash arduino_101, instead of
setting DFUUTIL_PID, DFUUTIL_ALT, and DFUUTIL_IMG environment
variables, have the script invocation look like this:

  python3 .../zephyr_flash_debug.py dfu-util flash \
          [common arguments omitted] \
          --pid=8087:0aba --alt=x86_app \
          --img=.../build/zephyr/zephyr.bin

Make similar changes for other runners (openocd, etc.) and
targets (debug, debugserver).

To implement this in the scripts:

  - have the individual scripts/support/runner/some-runner.py files
    register their own command line arguments

  - teach them to construct instances from arguments, not the
    environment

  - have zephyr_flash_debug.py request runners to register command
    line argument parsers, and handle arguments

In the build system:

  - add a new board_runner_args() extension function that board.cmake
    files can use to add to the zephyr_flash_debug.py command line

  - adjust cmake/flash/CMakeLists.txt to invoke with arguments

  - add new helper include files for each runner (like
    boards/common/dfu-util.board.cmake, etc.), which add default
    options as needed and then add on overrides from
    board_runner_args() calls

  - update board.cmake files to use the new includes and extension

This implied some tweaking when using openocd to make the CMake string
escaping and unescaping work properly.

Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
2017-12-15 09:57:30 -05:00

247 lines
8.9 KiB
CMake
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 applications .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 "")