cmake: Add partition table, and .bin file targets

This commit is contained in:
Angus Gratton 2018-01-19 15:47:49 +11:00 committed by Angus Gratton
parent 3ae4822115
commit 674d398c93
8 changed files with 156 additions and 64 deletions

View file

@ -1,24 +1,21 @@
cmake_minimum_required(VERSION 3.5)
set(CMAKE_TOOLCHAIN_FILE $ENV{IDF_PATH}/toolchain.cmake)
project(idf_bootloader ASM C CXX)
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)
if(NOT SDKCONFIG)
message(FATAL_ERROR "Bootloader subproject expects the SDKCONFIG variable to be passed in by the app build process.")
endif()
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
add_executable(bootloader.elf
main/bootloader_start.c
set(MAIN_SRCS main/bootloader_start.c
main/flash_qio_mode.c)
target_link_libraries(bootloader.elf ${COMPONENT_LIBRARIES})
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
target_link_libraries(bootloader.elf "-L ${CMAKE_CURRENT_SOURCE_DIR}/main")
target_link_libraries(bootloader.elf "-T esp32.bootloader.ld")

View file

@ -0,0 +1,48 @@
# Set some global esptool.py variables
set(ESPTOOLPY "${PYTHON}" "${CMAKE_CURRENT_LIST_DIR}/esptool/esptool.py" --chip esp32)
set(ESPSECUREPY "${PYTHON}" "${CMAKE_CURRENT_LIST_DIR}/esptool/espsecure.py")
set(ESPPORT $ENV{ESPPORT})
if(NOT ESPPORT)
set(ESPPORT ${CONFIG_ESPTOOLPY_PORT})
endif()
set(ESPBAUD $ENV{ESPPORT})
if(NOT ESPBAUD)
set(ESPPORT ${CONFIG_ESPTOOLPY_PORT})
endif()
set(ESPFLASHMODE ${CONFIG_ESPTOOLPY_FLASHMODE})
set(ESPFLASHFREQ ${CONFIG_ESPTOOLPY_FLASHFREQ})
set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE})
set(ESPTOOLPY_SERIAL "${ESPTOOLPY}" --port "${ESPPORT}" --baud ${ESPBAUD})
if(CONFIG_ESPTOOLPY_FLASHSIZE_DETECT)
set(flashsize_arg detect)
else()
set(flashsize_arg ${ESPFLASHSIZE})
endif()
set(ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS --flash_mode ${ESPFLASHMODE} --flash_freq ${ESPFLASHFREQ} --flash_size ${ESPFLASHSIZE})
set(ESPTOOLPY_WRITE_FLASH_OPTIONS --flash_mode ${ESPFLASHMODE} --flash_freq ${ESPFLASHFREQ} --flash_size ${flashsize_Arg})
set(ESPTOOLPY_WRITE_FLASH ${ESPTOOLPY_SERIAL} write_flash ${ESPTOOLPY_WRITE_FLASH_OPTIONS})
#
# Add 'binary' target - generates with elf2image
#
add_custom_command(OUTPUT "${PROJECT_NAME}.bin"
COMMAND ${ESPTOOLPY} elf2image ${ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS} -o "${PROJECT_NAME}.bin" "${PROJECT_NAME}.elf"
DEPENDS ${PROJECT_NAME}.elf
VERBATIM
)
add_custom_target(binary ALL DEPENDS "${PROJECT_NAME}.bin")
#
# Add 'flash' target - not all build systems can run this directly
#
add_custom_target(flash DEPENDS binary partition_table bootloader_subproject)
# TODO: this target should call "idftool" not esptool directly, so it can
# override things (port, baud, etc) at runtime not configure time

View file

@ -20,27 +20,34 @@ else()
set(final_partition_target "build_partition_table")
endif()
add_custom_target(build_partition_table ALL
"${PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py" -q
${partition_csv} ${unsigned_partition_bin}
BYPRODUCTS ${unsigned_partition_bin}
DEPENDS ${partition_csv} "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py"
VERBATIM)
if(CONFIG_PARTITION_TABLE_MD5)
set(md5_opt --disable-md5sum)
endif()
if(CONFIG_ESPTOOLPY_FLASHSIZE)
set(flashsize_opt --flash-size ${CONFIG_ESPTOOLPY_FLASHSIZE})
endif()
add_custom_command(OUTPUT "${unsigned_partition_bin}"
COMMAND "${PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py" -q ${md5_opt} ${flashsize_opt}
${partition_csv} ${unsigned_partition_bin}
DEPENDS ${partition_csv} "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py"
VERBATIM)
# Add signing steps
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
get_filename_component(secure_boot_signing_key "${CONFIG_SECURE_BOOT_SIGNING_KEY}" ABSOLUTE BASE_DIR "${PROJECT_PATH}")
add_custom_target(signpartition_table ALL
"${PYTHON}" "${ESPSECUREPY}" sign_data --keyfile "${secure_boot_signing_key}" -o "${final_partition_bin}" "${unsigned_partition_bin}"
BYPRODUCTS "${final_partition_bin}"
add_custom_command(OUTPUT "${final_partition_bin}"
COMMAND "${PYTHON}" "${ESPSECUREPY}" sign_data --keyfile "${secure_boot_signing_key}" -o "${final_partition_bin}" "${unsigned_partition_bin}"
DEPENDS "${unsigned_partition_bin}"
VERBATIM)
endif()
# Use global properties ESPTOOL_WRITE_FLASH_ARGS & FLASH_DEPENDS to pass this info to the esptool component for flashing
set_property(GLOBAL APPEND_STRING PROPERTY ESPTOOL_WRITE_FLASH_ARGS "${final_partition_bin} ${partition_table_offset} ")
set_property(GLOBAL APPEND PROPERTY FLASH_DEPENDS "${final_partition_target}")
add_custom_target(partition_table ALL DEPENDS "${final_partition_bin}")
# Use global properties ESPTOOL_WRITE_FLASH_ARGS to pass this info to build hte list of esptool write arguments for flashing
set_property(GLOBAL APPEND_STRING PROPERTY ESPTOOL_WRITE_FLASH_ARGS "${partition_table_offset} ${final_partition_bin} ")
register_config_only_component()

View file

@ -1,12 +1,10 @@
# The following four lines of boilerplate have to be in your project's CMakeLists
# 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(idf_project ASM C CXX)
project(hello-world ASM C CXX)
set(MAIN_SRCS main/hello_world_main.c)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
add_executable(hello_world.elf
main/hello_world_main.c)
target_link_libraries(hello_world.elf ${COMPONENT_LIBRARIES})

View file

@ -76,6 +76,15 @@ function(register_component)
endforeach()
endif()
# add public includes from other components when building this component
if(COMPONENT_SRCS OR embed_binaries)
add_library(${component} STATIC ${COMPONENT_SRCS})
set(include_type PUBLIC)
else()
add_library(${component} INTERFACE) # header-only component
set(include_type INTERFACE)
endif()
# binaries to embed directly in library
spaces2list(COMPONENT_EMBED_FILES)
spaces2list(COMPONENT_EMBED_TXTFILES)
@ -88,20 +97,13 @@ function(register_component)
target_add_binary_data("${component}" "${embed_data}" "${embed_type}")
endforeach()
# add public includes from other components when building this component
if(COMPONENT_SRCS OR embed_binaries)
add_library(${component} STATIC ${COMPONENT_SRCS} ${embed_binaries})
set(include_type PUBLIC)
else()
add_library(${component} INTERFACE) # header-only component
set(include_type INTERFACE)
endif(COMPONENT_SRCS OR embed_binaries)
# add public includes
foreach(include_dir ${COMPONENT_ADD_INCLUDEDIRS})
get_filename_component(include_dir ${include_dir} ABSOLUTE BASE_DIR ${component_dir})
target_include_directories(${component} ${include_type} ${include_dir})
endforeach()
# add private includes
foreach(include_dir ${COMPONENT_PRIV_INCLUDEDIRS})
if (${include_type} STREQUAL INTERFACE)
message(FATAL_ERROR "Component ${component} can't have no source files and COMPONENT_PRIV_INCLUDEDIRS set.")
@ -123,10 +125,10 @@ function(components_finish_registration)
# each component should see the include directories of each other
#
# (we can't do this until all components are registered, because if(TARGET ...) won't work
foreach(a ${COMPONENTS})
foreach(a ${COMPONENTS} ${CMAKE_PROJECT_NAME}.elf)
if (TARGET ${a})
get_target_property(a_type ${a} TYPE)
if (${a_type} STREQUAL STATIC_LIBRARY)
if (${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
foreach(b ${COMPONENTS})
if (TARGET ${b} AND NOT ${a} STREQUAL ${b})
# Add all public compile options from b in a
@ -138,15 +140,14 @@ function(components_finish_registration)
$<TARGET_PROPERTY:${b},INTERFACE_COMPILE_OPTIONS>)
endif()
endforeach(b)
endif(${a_type} STREQUAL STATIC_LIBRARY)
endif(${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
set(COMPONENT_LIBRARIES "${COMPONENT_LIBRARIES};${a}")
if (${a_type} MATCHES .+_LIBRARY)
set(COMPONENT_LIBRARIES "${COMPONENT_LIBRARIES};${a}")
endif()
endif()
endforeach()
# set COMPONENT_LIBRARIES in top-level scope
set(COMPONENT_LIBRARIES "${COMPONENT_LIBRARIES}" PARENT_SCOPE)
# Embedded binary & text files
spaces2list(COMPONENT_EMBED_FILES)
foreach(embed_src ${COMPONENT_EMBED_FILES})
@ -157,4 +158,6 @@ function(components_finish_registration)
target_add_binary_data(${component} "${embed_src}" TEXT)
endforeach()
target_link_libraries(${CMAKE_PROJECT_NAME}.elf ${COMPONENT_LIBRARIES})
endfunction(components_finish_registration)

View file

@ -3,6 +3,7 @@
include(crosstool_version_check)
macro(idf_set_global_variables)
# Note that CONFIG_xxx is not available when this function is called
set_default(EXTRA_COMPONENT_DIRS "")
@ -18,6 +19,9 @@ macro(idf_set_global_variables)
spaces2list(COMPONENTS)
# Tell cmake to drop executables in the top-level build dir
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
endmacro()
# Add all the IDF global compiler & preprocessor options
@ -76,27 +80,18 @@ function(idf_set_global_compiler_options)
endfunction(idf_set_global_compiler_options)
# Override add_executable to add IDF-specific
# linker flags & map file to all built executables
function(add_executable target)
get_filename_component(basename ${target} NAME_WE)
set(mapfile "${basename}.map")
_add_executable(${ARGV})
target_link_libraries(${target} "-Wl,--gc-sections -Wl,--cref -Wl,--Map=${mapfile} -Wl,--start-group")
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${mapfile}")
endfunction(add_executable)
# Verify the IDF environment is configured correctly (environment, toolchain, etc)
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")
endif()
# Check toolchain is configured properly in cmake
if(NOT ( ${CMAKE_SYSTEM_NAME} STREQUAL "Generic" AND ${CMAKE_C_COMPILER} MATCHES xtensa))
message(FATAL_ERROR "The parent project CMakeLists.txt file needs to set CMAKE_TOOLCHAIN_FILE "
"before including this file. "
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.")
endif()
@ -108,3 +103,28 @@ function(idf_verify_environment)
crosstool_version_check("1.22.0-80-g6c4433a")
endfunction()
# idf_add_executable
#
# Calls add_executable to add the final project executable
# Adds .map & .bin file targets
# Sets up flash-related targets
function(idf_add_executable)
set(exe_target ${PROJECT_NAME}.elf)
spaces2list(${MAIN_SRCS})
add_executable(${exe_target} "${MAIN_SRCS}")
add_map_file(${exe_target})
endfunction(idf_add_executable)
# add_map_file
#
# Set linker args for 'exe_target' to generate a linker Map file
function(add_map_file exe_target)
get_filename_component(basename ${exe_target} NAME_WE)
set(mapfile "${basename}.map")
target_link_libraries(${exe_target} "-Wl,--gc-sections -Wl,--cref -Wl,--Map=${mapfile} -Wl,--start-group")
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${mapfile}")
endfunction(add_map_file)

View file

@ -50,17 +50,31 @@ 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 components to the build
# 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()
#
# Finish component registration (add cross-dependencies, make
# executable dependent on all components.)
#
components_finish_registration()
# Load the targets for the bootloader subproject
# Define the external target to build the bootloader subproject
if(NOT BOOTLOADER_BUILD)
include(bootloader_subproject)
endif()

View file

@ -102,7 +102,7 @@ endfunction()
# to a binary object as part of the build
function(target_add_binary_data target embed_file embed_type)
get_filename_component(embed_file "${embed_file}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
get_filename_component(embed_file "${embed_file}" ABSOLUTE)
get_filename_component(name "${embed_file}" NAME)
set(embed_srcfile "${CMAKE_BINARY_DIR}/${name}.c")
@ -121,3 +121,8 @@ function(target_add_binary_data target embed_file embed_type)
target_sources("${target}" PRIVATE "${embed_srcfile}")
endfunction()
macro(include_if_exists path)
if(EXISTS "${path}")
include("${path}")
endif()
endmacro(include_if_exists)