cmake: Allow selecting toolchain file based on config

Refactor IDF "project" functionality under a wrapping of the default
"project" command, so we can tweak it a bit...

Will need more testing in other environments.
This commit is contained in:
Angus Gratton 2018-02-15 14:38:58 +11:00 committed by Angus Gratton
parent 04a944598f
commit abef220b13
6 changed files with 83 additions and 63 deletions

View file

@ -1,4 +1,4 @@
if(IS_BOOTLOADER_BUILD)
if(BOOTLOADER_BUILD)
return() # don't keep recursing!
endif()

View file

@ -1,20 +1,17 @@
cmake_minimum_required(VERSION 3.5)
set(CMAKE_TOOLCHAIN_FILE $ENV{IDF_PATH}/toolchain.cmake)
if(NOT SDKCONFIG)
message(FATAL_ERROR "Bootloader subproject expects the SDKCONFIG variable to be passed in by the parent build process.")
endif()
project(bootloader ASM C CXX)
set(COMPONENTS bootloader esptool_py esp32 soc bootloader_support log spi_flash micro-ecc soc)
set(BOOTLOADER_BUILD 1)
set(IS_BOOTLOADER_BUILD 1) # deprecated, use BOOTLOADER_BUILD
add_definitions(-DBOOTLOADER_BUILD=1)
set(MAIN_SRCS main/bootloader_start.c)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(bootloader)
target_link_libraries(bootloader.elf "-L ${CMAKE_CURRENT_SOURCE_DIR}/main")
target_link_libraries(bootloader.elf "-T esp32.bootloader.ld")

View file

@ -1,10 +1,8 @@
# The following five lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
set(CMAKE_TOOLCHAIN_FILE $ENV{IDF_PATH}/toolchain.cmake)
project(hello-world ASM C CXX)
set(MAIN_SRCS main/hello_world_main.c)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(hello-world)

View file

@ -2,6 +2,12 @@
include(crosstool_version_check)
#
# Set some variables used by rest of the build
#
# Note at the time this macro is expanded, the config is not yet
# loaded and the toolchain and project are not yet set
#
macro(idf_set_global_variables)
# Note that CONFIG_xxx is not available when this function is called
@ -22,9 +28,6 @@ macro(idf_set_global_variables)
# Tell cmake to drop executables in the top-level build dir
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
# cmake cross-toolchain doesn't include any gcc binutils names
set(CMAKE_OBJCOPY xtensa-esp32-elf-objcopy)
# path to idf.py tool
set(IDFTOOL ${PYTHON} "${IDF_PATH}/tools/idf.py")
@ -93,20 +96,18 @@ endfunction(idf_set_global_compiler_options)
function(idf_verify_environment)
if(NOT CMAKE_PROJECT_NAME)
message(FATAL_ERROR "Project top-level CMakeLists.txt file must call project() before including project.cmake")
message(FATAL_ERROR "Internal error, IDF project.cmake should have set this variable already")
endif()
# Check toolchain is configured properly in cmake
if(NOT ( ${CMAKE_SYSTEM_NAME} STREQUAL "Generic" AND ${CMAKE_C_COMPILER} MATCHES xtensa))
message(FATAL_ERROR "Project top-level CMakeLists.txt file needs to set CMAKE_TOOLCHAIN_FILE "
"before including project.cmake.\n"
"Update CMakeLists.txt to match the template project and delete CMakeCache.txt before "
"re-running cmake.")
message(FATAL_ERROR "Internal error, toolchain has not been set correctly by project")
endif()
#
# Warn if the toolchain version doesn't match
#
# TODO: make these platform-specific for diff toolchains
gcc_version_check("5.2.0")
crosstool_version_check("1.22.0-80-g6c4433a")

View file

@ -24,55 +24,79 @@ include(idf_functions)
set_default(PYTHON "python")
# Verify the environment is configured correctly
idf_verify_environment()
# Set global variables used by rest of the build
idf_set_global_variables()
# Search COMPONENT_DIRS for COMPONENTS, make a list of full paths to each component in COMPONENT_PATHS
components_find_all("${COMPONENT_DIRS}" "${COMPONENTS}" COMPONENT_PATHS COMPONENTS)
kconfig_set_variables()
kconfig_process_config()
# Include sdkconfig.cmake so rest of the build knows the configuration
include(${SDKCONFIG_CMAKE})
# Add some idf-wide definitions
idf_set_global_compiler_options()
# Check git version (may trigger reruns of cmake)
# & set GIT_REVISION/IDF_VER variable
git_describe(GIT_REVISION)
add_definitions(-DIDF_VER=\"${GIT_REVISION}\")
git_submodule_check("${IDF_PATH}")
# Include any top-level project_include.cmake files from components
foreach(component ${COMPONENT_PATHS})
include_if_exists("${component}/project_include.cmake")
endforeach()
# project
#
# Add each component to the build as a library
# This macro wraps the cmake 'project' command to add
# all of the IDF-specific functionality required
#
foreach(component ${COMPONENT_PATHS})
get_filename_component(component_name ${component} NAME)
add_subdirectory(${component} ${component_name})
endforeach()
# Implementation Note: This macro wraps 'project' on purpose, because cmake has some
# backwards-compatible magic where if you don't call "project" in the top-level
# CMakeLists file, it will call it implicitly. However, the implict project will not
# have CMAKE_TOOLCHAIN_FILE set and therefore tries to create a native build project.
#
# Therefore, to keep all the IDF "build magic", the cleanest way is to keep the
# top-level "project" call but customize it to do what we want in the IDF build...
#
macro(project name)
# Set global variables used by rest of the build
idf_set_global_variables()
#
# Add the app executable to the build (has name of PROJECT.elf)
#
idf_add_executable()
# Search COMPONENT_DIRS for COMPONENTS, make a list of full paths to each component in COMPONENT_PATHS
components_find_all("${COMPONENT_DIRS}" "${COMPONENTS}" COMPONENT_PATHS COMPONENTS)
# Write project description JSON file
configure_file("${CMAKE_CURRENT_LIST_DIR}/project_description.json.in"
"${CMAKE_BINARY_DIR}/project_description.json")
kconfig_set_variables()
#
# Finish component registration (add cross-dependencies, make
# executable dependent on all components)
#
components_finish_registration()
kconfig_process_config()
# Include sdkconfig.cmake so rest of the build knows the configuration
include(${SDKCONFIG_CMAKE})
# Now the configuration is loaded, set the toolchain appropriately
#
# TODO: support more toolchains than just ESP32
set(CMAKE_TOOLCHAIN_FILE $ENV{IDF_PATH}/tools/cmake/toolchain-esp32.cmake)
# Declare the actual cmake-level project
_project(${name} ASM C CXX)
# Verify the environment is configured correctly
idf_verify_environment()
# Add some idf-wide definitions
idf_set_global_compiler_options()
# Check git version (may trigger reruns of cmake)
# & set GIT_REVISION/IDF_VER variable
git_describe(GIT_REVISION)
add_definitions(-DIDF_VER=\"${GIT_REVISION}\")
git_submodule_check("${IDF_PATH}")
# Include any top-level project_include.cmake files from components
foreach(component ${COMPONENT_PATHS})
include_if_exists("${component}/project_include.cmake")
endforeach()
#
# Add each component to the build as a library
#
foreach(component ${COMPONENT_PATHS})
get_filename_component(component_name ${component} NAME)
add_subdirectory(${component} ${component_name})
endforeach()
#
# Add the app executable to the build (has name of PROJECT.elf)
#
idf_add_executable()
# Write project description JSON file
configure_file("${IDF_PATH}/tools/cmake/project_description.json.in"
"${CMAKE_BINARY_DIR}/project_description.json")
#
# Finish component registration (add cross-dependencies, make
# executable dependent on all components)
#
components_finish_registration()
endmacro(project)