From abef220b13e8837705e1a8bd30a2ad526f64ebd2 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 15 Feb 2018 14:38:58 +1100 Subject: [PATCH] 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. --- components/bootloader/project_include.cmake | 2 +- .../bootloader/subproject/CMakeLists.txt | 5 +- .../get-started/hello_world/CMakeLists.txt | 4 +- tools/cmake/idf_functions.cmake | 17 +-- tools/cmake/project.cmake | 104 +++++++++++------- .../cmake/toolchain-esp32.cmake | 0 6 files changed, 76 insertions(+), 56 deletions(-) rename toolchain.cmake => tools/cmake/toolchain-esp32.cmake (100%) diff --git a/components/bootloader/project_include.cmake b/components/bootloader/project_include.cmake index bfefcb8a2a..cef56f47e7 100644 --- a/components/bootloader/project_include.cmake +++ b/components/bootloader/project_include.cmake @@ -1,4 +1,4 @@ -if(IS_BOOTLOADER_BUILD) +if(BOOTLOADER_BUILD) return() # don't keep recursing! endif() diff --git a/components/bootloader/subproject/CMakeLists.txt b/components/bootloader/subproject/CMakeLists.txt index ae24d8ceeb..e5d2c18bf0 100644 --- a/components/bootloader/subproject/CMakeLists.txt +++ b/components/bootloader/subproject/CMakeLists.txt @@ -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") diff --git a/examples/get-started/hello_world/CMakeLists.txt b/examples/get-started/hello_world/CMakeLists.txt index 4ae205fa25..e0b4ccdeff 100644 --- a/examples/get-started/hello_world/CMakeLists.txt +++ b/examples/get-started/hello_world/CMakeLists.txt @@ -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) diff --git a/tools/cmake/idf_functions.cmake b/tools/cmake/idf_functions.cmake index 458425f335..9cab9bb569 100644 --- a/tools/cmake/idf_functions.cmake +++ b/tools/cmake/idf_functions.cmake @@ -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") diff --git a/tools/cmake/project.cmake b/tools/cmake/project.cmake index b23f39d731..7ed6b190d4 100644 --- a/tools/cmake/project.cmake +++ b/tools/cmake/project.cmake @@ -24,55 +24,79 @@ include(idf_functions) set_default(PYTHON "python") -# Verify the environment is configured correctly -idf_verify_environment() +# project +# +# This macro wraps the cmake 'project' command to add +# all of the IDF-specific functionality required +# +# 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() -# 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) -# 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_set_variables() + kconfig_process_config() -kconfig_process_config() + # Include sdkconfig.cmake so rest of the build knows the configuration + include(${SDKCONFIG_CMAKE}) -# 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) -# Add some idf-wide definitions -idf_set_global_compiler_options() + # Declare the actual cmake-level project + _project(${name} ASM C CXX) -# 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}") + # Verify the environment is configured correctly + idf_verify_environment() -# Include any top-level project_include.cmake files from components -foreach(component ${COMPONENT_PATHS}) - include_if_exists("${component}/project_include.cmake") -endforeach() + # Add some idf-wide definitions + idf_set_global_compiler_options() -# -# 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() + # 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}") -# -# Add the app executable to the build (has name of PROJECT.elf) -# -idf_add_executable() + # Include any top-level project_include.cmake files from components + foreach(component ${COMPONENT_PATHS}) + include_if_exists("${component}/project_include.cmake") + endforeach() -# Write project description JSON file -configure_file("${CMAKE_CURRENT_LIST_DIR}/project_description.json.in" - "${CMAKE_BINARY_DIR}/project_description.json") + # + # 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() -# -# Finish component registration (add cross-dependencies, make -# executable dependent on all components) -# -components_finish_registration() + # + # 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) diff --git a/toolchain.cmake b/tools/cmake/toolchain-esp32.cmake similarity index 100% rename from toolchain.cmake rename to tools/cmake/toolchain-esp32.cmake -- 2.40.0