cmake: Use cmake_lint project, tidy up all CMake source files

This commit is contained in:
Angus Gratton 2018-02-27 15:45:30 +11:00 committed by Angus Gratton
parent 15d5e88618
commit 88df8fd293
32 changed files with 962 additions and 882 deletions

View File

@ -32,3 +32,8 @@ insert_final_newline = false
[*.py] [*.py]
max_line_length = 119 max_line_length = 119
[{*.cmake,CMakeLists.txt}]
indent_style = space
indent_size = 4
max_line_length = 120

View File

@ -1,8 +1,8 @@
if(CONFIG_AWS_IOT_SDK) if(NOT CONFIG_AWS_IOT_SDK)
return()
endif()
set(COMPONENT_ADD_INCLUDEDIRS "include aws-iot-device-sdk-embedded-C/include") set(COMPONENT_ADD_INCLUDEDIRS "include aws-iot-device-sdk-embedded-C/include")
set(COMPONENT_SRCDIRS "aws-iot-device-sdk-embedded-C/src port") set(COMPONENT_SRCDIRS "aws-iot-device-sdk-embedded-C/src port")
register_component() register_component()
endif(CONFIG_AWS_IOT_SDK)

View File

@ -1,5 +1,5 @@
if(BOOTLOADER_BUILD) if(BOOTLOADER_BUILD)
return() # don't keep recursing! return() # don't keep recursing!
endif() endif()
# Glue to build the bootloader subproject binary as an external # Glue to build the bootloader subproject binary as an external
@ -8,24 +8,26 @@ endif()
# #
set(bootloader_build_dir "${CMAKE_BINARY_DIR}/bootloader") set(bootloader_build_dir "${CMAKE_BINARY_DIR}/bootloader")
set(bootloader_binary_files set(bootloader_binary_files
"${bootloader_build_dir}/bootloader.elf" "${bootloader_build_dir}/bootloader.elf"
"${bootloader_build_dir}/bootloader.bin" "${bootloader_build_dir}/bootloader.bin"
"${bootloader_build_dir}/bootloader.map" "${bootloader_build_dir}/bootloader.map"
) )
ExternalProject_Add(bootloader externalproject_add(bootloader
# TODO: support overriding the bootloader in COMPONENT_PATHS # TODO: support overriding the bootloader in COMPONENT_PATHS
SOURCE_DIR "${IDF_PATH}/components/bootloader/subproject" SOURCE_DIR "${IDF_PATH}/components/bootloader/subproject"
BINARY_DIR "${bootloader_build_dir}" BINARY_DIR "${bootloader_build_dir}"
CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH="${IDF_PATH}" CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH="${IDF_PATH}"
INSTALL_COMMAND "" INSTALL_COMMAND ""
BUILD_ALWAYS 1 # no easy way around this... BUILD_ALWAYS 1 # no easy way around this...
BUILD_BYPRODUCTS ${bootloader_binary_files} BUILD_BYPRODUCTS ${bootloader_binary_files}
) )
# this is a hack due to an (annoying) shortcoming in cmake, it can't # this is a hack due to an (annoying) shortcoming in cmake, it can't
# extend the 'clean' target to the external project # extend the 'clean' target to the external project
# see thread: https://cmake.org/pipermail/cmake/2016-December/064660.html # see thread: https://cmake.org/pipermail/cmake/2016-December/064660.html
# #
# So for now we just have the top-level build remove the final build products... # So for now we just have the top-level build remove the final build products...
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${bootloader_binary_files}) set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
${bootloader_binary_files})

View File

@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
if(NOT SDKCONFIG) if(NOT SDKCONFIG)
message(FATAL_ERROR "Bootloader subproject expects the SDKCONFIG variable to be passed in by the parent build process.") message(FATAL_ERROR "Bootloader subproject expects the SDKCONFIG variable to be passed "
"in by the parent build process.")
endif() endif()
set(COMPONENTS bootloader esptool_py esp32 soc bootloader_support log spi_flash micro-ecc soc) set(COMPONENTS bootloader esptool_py esp32 soc bootloader_support log spi_flash micro-ecc soc)
@ -18,4 +19,3 @@ target_link_libraries(bootloader.elf "-T esp32.bootloader.ld")
target_link_libraries(bootloader.elf "-T esp32.bootloader.rom.ld") target_link_libraries(bootloader.elf "-T esp32.bootloader.rom.ld")
target_link_libraries(bootloader.elf "${BOOTLOADER_LINKER_ARGS}") target_link_libraries(bootloader.elf "${BOOTLOADER_LINKER_ARGS}")
target_link_libraries(bootloader.elf gcc) target_link_libraries(bootloader.elf gcc)

View File

@ -1,10 +1,10 @@
set(COMPONENT_SRCDIRS "src") set(COMPONENT_SRCDIRS "src")
if(${BOOTLOADER_BUILD}) if(${BOOTLOADER_BUILD})
set(COMPONENT_ADD_INCLUDEDIRS "include include_priv") set(COMPONENT_ADD_INCLUDEDIRS "include include_priv")
else() else()
set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_ADD_INCLUDEDIRS "include")
set(COMPONENT_PRIV_INCLUDEDIRS "include_priv") set(COMPONENT_PRIV_INCLUDEDIRS "include_priv")
endif() endif()
register_component() register_component()

View File

@ -1,99 +1,97 @@
if(CONFIG_BT_ENABLED) if(NOT CONFIG_BT_ENABLED)
return()
endif()
set(COMPONENT_SRCDIRS .) set(COMPONENT_SRCDIRS .)
set(COMPONENT_ADD_INCLUDEDIRS include) set(COMPONENT_ADD_INCLUDEDIRS include)
target_link_libraries("-L ${CMAKE_CURRENT_LIST_DIR}/lib") target_link_libraries("-L ${CMAKE_CURRENT_LIST_DIR}/lib")
target_link_libraries(bt btdm_app) target_link_libraries(bt btdm_app)
if(CONFIG_BLUEDROID_ENABLED) if(CONFIG_BLUEDROID_ENABLED)
set(COMPONENT_ADD_INCLUDEDIRS ${COMPONENT_ADD_INCLUDEDIRS} set(COMPONENT_ADD_INCLUDEDIRS ${COMPONENT_ADD_INCLUDEDIRS}
bluedroid/bta/include bluedroid/bta/include
bluedroid/bta/sys/include bluedroid/bta/sys/include
bluedroid/btcore/include bluedroid/btcore/include
bluedroid/device/include bluedroid/device/include
bluedroid/gki/include bluedroid/gki/include
bluedroid/hci/include bluedroid/hci/include
bluedroid/osi/include bluedroid/osi/include
bluedroid/utils/include bluedroid/utils/include
bluedroid/external/sbc/decoder/include bluedroid/external/sbc/decoder/include
bluedroid/btc/core/include bluedroid/btc/core/include
bluedroid/btc/profile/esp/blufi/include bluedroid/btc/profile/esp/blufi/include
bluedroid/btc/profile/esp/include bluedroid/btc/profile/esp/include
bluedroid/btc/profile/std/gatt/include bluedroid/btc/profile/std/gatt/include
bluedroid/btc/profile/std/gap/include bluedroid/btc/profile/std/gap/include
bluedroid/btc/profile/std/a2dp/include bluedroid/btc/profile/std/a2dp/include
bluedroid/btc/profile/std/include bluedroid/btc/profile/std/include
bluedroid/btc/include bluedroid/btc/include
bluedroid/btif/include bluedroid/btif/include
bluedroid/stack/btm/include bluedroid/stack/btm/include
bluedroid/stack/btu/include bluedroid/stack/btu/include
bluedroid/stack/gap/include bluedroid/stack/gap/include
bluedroid/stack/gatt/include bluedroid/stack/gatt/include
bluedroid/stack/hcic/include bluedroid/stack/hcic/include
bluedroid/stack/l2cap/include bluedroid/stack/l2cap/include
bluedroid/stack/sdp/include bluedroid/stack/sdp/include
bluedroid/stack/smp/include bluedroid/stack/smp/include
bluedroid/stack/avct/include bluedroid/stack/avct/include
bluedroid/stack/avrc/include bluedroid/stack/avrc/include
bluedroid/stack/avdt/include bluedroid/stack/avdt/include
bluedroid/stack/a2dp/include bluedroid/stack/a2dp/include
bluedroid/stack/rfcomm/include bluedroid/stack/rfcomm/include
bluedroid/stack/include bluedroid/stack/include
bluedroid/utils/include bluedroid/utils/include
bluedroid/api/include bluedroid/api/include
bluedroid/include) bluedroid/include)
set(COMPONENT_SRCDIRS ${COMPONENT_SRCDIRS} set(COMPONENT_SRCDIRS ${COMPONENT_SRCDIRS}
bluedroid/bta/dm bluedroid/bta/dm
bluedroid/bta/gatt bluedroid/bta/gatt
bluedroid/bta/hh bluedroid/bta/hh
bluedroid/bta/sdp bluedroid/bta/sdp
bluedroid/bta/av bluedroid/bta/av
bluedroid/bta/ar bluedroid/bta/ar
bluedroid/bta/sys bluedroid/bta/sys
bluedroid/bta/jv bluedroid/bta/jv
bluedroid/bta bluedroid/bta
bluedroid/btcore bluedroid/btcore
bluedroid/btif bluedroid/btif
bluedroid/device bluedroid/device
bluedroid/gki bluedroid/gki
bluedroid/hci bluedroid/hci
bluedroid/main bluedroid/main
bluedroid/osi bluedroid/osi
bluedroid/external/sbc/decoder/srce bluedroid/external/sbc/decoder/srce
bluedroid/btc/core bluedroid/btc/core
bluedroid/btc/profile/esp/blufi bluedroid/btc/profile/esp/blufi
bluedroid/btc/profile/std/gap bluedroid/btc/profile/std/gap
bluedroid/btc/profile/std/gatt bluedroid/btc/profile/std/gatt
bluedroid/btc/profile/std/a2dp bluedroid/btc/profile/std/a2dp
bluedroid/btc/profile/std/avrc bluedroid/btc/profile/std/avrc
bluedroid/btc/profile/std/spp bluedroid/btc/profile/std/spp
bluedroid/btc/profile bluedroid/btc/profile
bluedroid/stack/btm bluedroid/stack/btm
bluedroid/stack/btu bluedroid/stack/btu
bluedroid/stack/gap bluedroid/stack/gap
bluedroid/stack/gatt bluedroid/stack/gatt
bluedroid/stack/hcic bluedroid/stack/hcic
bluedroid/stack/include bluedroid/stack/include
bluedroid/stack/l2cap bluedroid/stack/l2cap
bluedroid/stack/sdp bluedroid/stack/sdp
bluedroid/stack/smp bluedroid/stack/smp
bluedroid/stack/avct bluedroid/stack/avct
bluedroid/stack/avrc bluedroid/stack/avrc
bluedroid/stack/avdt bluedroid/stack/avdt
bluedroid/stack/a2dp bluedroid/stack/a2dp
bluedroid/stack/rfcomm bluedroid/stack/rfcomm
bluedroid/stack bluedroid/stack
bluedroid/utils bluedroid/utils
bluedroid/api bluedroid/api
bluedroid) bluedroid)
endif(CONFIG_BLUEDROID_ENABLED)
register_component()
endif(CONFIG_BT_ENABLED)
endif()
register_component()

View File

@ -1,31 +1,28 @@
set(COMPONENT_ADD_INCLUDEDIRS port/include port/include/coap libcoap/include libcoap/include/coap) set(COMPONENT_ADD_INCLUDEDIRS port/include port/include/coap libcoap/include libcoap/include/coap)
set(COMPONENT_SRCS set(COMPONENT_SRCS
libcoap/src/address.c libcoap/src/address.c
libcoap/src/async.c libcoap/src/async.c
libcoap/src/block.c libcoap/src/block.c
libcoap/src/coap_time.c libcoap/src/coap_time.c
libcoap/src/debug.c libcoap/src/debug.c
libcoap/src/encode.c libcoap/src/encode.c
libcoap/src/hashkey.c libcoap/src/hashkey.c
libcoap/src/mem.c libcoap/src/mem.c
libcoap/src/net.c libcoap/src/net.c
libcoap/src/option.c libcoap/src/option.c
libcoap/src/pdu.c libcoap/src/pdu.c
libcoap/src/resource.c libcoap/src/resource.c
libcoap/src/str.c libcoap/src/str.c
libcoap/src/subscribe.c libcoap/src/subscribe.c
libcoap/src/uri.c libcoap/src/uri.c
port/coap_io_socket.c port/coap_io_socket.c
) )
register_component() register_component()
# Needed for coap headers in public builds, also. # Needed for coap headers in public builds, also.
# #
# TODO: find a way to move this to a port header # TODO: find a way to move this to a port header
target_compile_definitions(coap PUBLIC target_compile_definitions(coap PUBLIC WITH_POSIX)
WITH_POSIX
)

View File

@ -6,5 +6,5 @@ target_link_libraries(cxx stdc++)
target_link_libraries(cxx "-u __cxa_guard_dummy") target_link_libraries(cxx "-u __cxa_guard_dummy")
if(NOT CONFIG_CXX_EXCEPTIONS) if(NOT CONFIG_CXX_EXCEPTIONS)
target_link_libraries(cxx "-u __cxx_fatal_exception") target_link_libraries(cxx "-u __cxx_fatal_exception")
endif() endif()

View File

@ -1,77 +1,86 @@
if(BOOTLOADER_BUILD) if(BOOTLOADER_BUILD)
# For bootloader, all we need from esp32 is headers # For bootloader, all we need from esp32 is headers
add_library(esp32 INTERFACE) add_library(esp32 INTERFACE)
target_include_directories(esp32 INTERFACE include) target_include_directories(esp32 INTERFACE include)
# as cmake won't attach linker args to a header-only library, attach # as cmake won't attach linker args to a header-only library, attach
# linker args directly to the bootloader.elf # linker args directly to the bootloader.elf
set(BOOTLOADER_LINKER_ARGS "-L ${CMAKE_CURRENT_SOURCE_DIR}/ld -T esp32.rom.ld -Tesp32.rom.spiram_incompatible_fns.ld -T esp32.peripherals.ld" PARENT_SCOPE) set(BOOTLOADER_LINKER_ARGS
"-L ${CMAKE_CURRENT_SOURCE_DIR}/ld"
"-T esp32.rom.ld"
"-T esp32.rom.spiram_incompatible_fns.ld"
"-T esp32.peripherals.ld"
PARENT_SCOPE)
else() else()
# Regular app build # Regular app build
set(COMPONENT_SRCDIRS ". hwcrypto") set(COMPONENT_SRCDIRS ". hwcrypto")
set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_ADD_INCLUDEDIRS "include")
register_component() register_component()
target_link_libraries(esp32 "-L ${CMAKE_CURRENT_SOURCE_DIR}/lib") target_link_libraries(esp32 "-L ${CMAKE_CURRENT_SOURCE_DIR}/lib")
if(NOT CONFIG_NO_BLOBS) if(NOT CONFIG_NO_BLOBS)
target_link_libraries(esp32 coexist core espnow net80211 phy pp rtc smartconfig wpa2 wpa wps) target_link_libraries(esp32 coexist core espnow net80211 phy pp rtc smartconfig wpa2 wpa wps)
endif() endif()
target_link_libraries(esp32 "-L ${CMAKE_CURRENT_SOURCE_DIR}/ld") target_link_libraries(esp32 "-L ${CMAKE_CURRENT_SOURCE_DIR}/ld")
target_link_libraries(esp32 "-T ${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld") target_link_libraries(esp32 "-T ${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld")
target_link_libraries(esp32 "-T esp32.common.ld") target_link_libraries(esp32 "-T esp32.common.ld")
target_link_libraries(esp32 "-T esp32.rom.ld") target_link_libraries(esp32 "-T esp32.rom.ld")
target_link_libraries(esp32 "-T esp32.peripherals.ld") target_link_libraries(esp32 "-T esp32.peripherals.ld")
if(CONFIG_SPIRAM_CACHE_WORKAROUND) if(CONFIG_SPIRAM_CACHE_WORKAROUND)
target_link_libraries(esp32 ${CMAKE_CURRENT_SOURCE_DIR}/libstdc++-psram-workaround.a) target_link_libraries(esp32 ${CMAKE_CURRENT_SOURCE_DIR}/libstdc++-psram-workaround.a)
else() else()
target_link_libraries(esp32 "-T esp32.rom.spiram_incompatible_fns.ld") target_link_libraries(esp32 "-T esp32.rom.spiram_incompatible_fns.ld")
endif() endif()
if(CONFIG_NEWLIB_NANO_FORMAT) if(CONFIG_NEWLIB_NANO_FORMAT)
target_link_libraries(esp32 "-T esp32.rom.nanofmt.ld") target_link_libraries(esp32 "-T esp32.rom.nanofmt.ld")
endif() endif()
if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH) if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH)
target_link_libraries(esp32 "-T esp32.rom.spiflash.ld") target_link_libraries(esp32 "-T esp32.rom.spiflash.ld")
endif() endif()
target_link_libraries(esp32 "${CMAKE_CURRENT_SOURCE_DIR}/libhal.a") target_link_libraries(esp32 "${CMAKE_CURRENT_SOURCE_DIR}/libhal.a")
target_link_libraries(esp32 gcc) target_link_libraries(esp32 gcc)
target_link_libraries(esp32 "-u call_user_start_cpu0") target_link_libraries(esp32 "-u call_user_start_cpu0")
#ld_include_panic_highint_hdl is added as an undefined symbol because otherwise the #ld_include_panic_highint_hdl is added as an undefined symbol because otherwise the
#linker will ignore panic_highint_hdl.S as it has no other files depending on any #linker will ignore panic_highint_hdl.S as it has no other files depending on any
#symbols in it. #symbols in it.
target_link_libraries(esp32 "-u ld_include_panic_highint_hdl") target_link_libraries(esp32 "-u ld_include_panic_highint_hdl")
# Preprocess esp32.ld linker script to include configuration, becomes esp32_out.ld # Preprocess esp32.ld linker script to include configuration, becomes esp32_out.ld
set(LD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ld) set(LD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ld)
add_custom_command(
OUTPUT esp32_out.ld
COMMAND "${CMAKE_C_COMPILER}" -C -P -x c -E -o esp32_out.ld -I ${CMAKE_BINARY_DIR} ${LD_DIR}/esp32.ld
MAIN_DEPENDENCY ${LD_DIR}/esp32.ld
COMMENT "Generating linker script..."
VERBATIM)
add_custom_target(esp32_linker_script DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld)
add_dependencies(esp32 esp32_linker_script)
if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION)
set(PHY_INIT_DATA_BIN phy_init_data.bin)
# To get the phy_init_data.bin file, compile phy_init_data.h as a C file and then objcopy the object file to a raw binary
add_custom_command( add_custom_command(
OUTPUT ${PHY_INIT_DATA_BIN} OUTPUT esp32_out.ld
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/phy_init_data.h COMMAND "${CMAKE_C_COMPILER}" -C -P -x c -E -o esp32_out.ld -I ${CMAKE_BINARY_DIR} ${LD_DIR}/esp32.ld
COMMAND ${CMAKE_C_COMPILER} -x c -c -o phy_init_data.obj -I ${CMAKE_CURRENT_LIST_DIR} -I ${CMAKE_CURRENT_LIST_DIR}/include -I ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/phy_init_data.h MAIN_DEPENDENCY ${LD_DIR}/esp32.ld
COMMAND ${CMAKE_OBJCOPY} -O binary phy_init_data.obj ${PHY_INIT_DATA_BIN} COMMENT "Generating linker script..."
) VERBATIM)
add_custom_target(phy_init_data ALL DEPENDS ${PHY_INIT_DATA_BIN}) add_custom_target(esp32_linker_script DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld)
add_dependencies(flash phy_init_data) add_dependencies(esp32 esp32_linker_script)
endif(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION) if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION)
set(PHY_INIT_DATA_BIN phy_init_data.bin)
endif(BOOTLOADER_BUILD) # To get the phy_init_data.bin file, compile phy_init_data.h as a C file and then objcopy
# the object file to a raw binary
add_custom_command(
OUTPUT ${PHY_INIT_DATA_BIN}
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/phy_init_data.h
COMMAND ${CMAKE_C_COMPILER} -x c -c
-I ${CMAKE_CURRENT_LIST_DIR} -I ${CMAKE_CURRENT_LIST_DIR}/include -I ${CMAKE_BINARY_DIR}
-o phy_init_data.obj
${CMAKE_CURRENT_LIST_DIR}/phy_init_data.h
COMMAND ${CMAKE_OBJCOPY} -O binary phy_init_data.obj ${PHY_INIT_DATA_BIN}
)
add_custom_target(phy_init_data ALL DEPENDS ${PHY_INIT_DATA_BIN})
add_dependencies(flash phy_init_data)
endif()
endif()

View File

@ -2,8 +2,8 @@ register_config_only_component()
# Generate pre-canned flasher args files suitable for passing to esptool.py # Generate pre-canned flasher args files suitable for passing to esptool.py
foreach(part project app bootloader) foreach(part project app bootloader)
configure_file( configure_file(
"${CMAKE_CURRENT_LIST_DIR}/flash_${part}_args.in" "${CMAKE_CURRENT_LIST_DIR}/flash_${part}_args.in"
"${CMAKE_BINARY_DIR}/flash_${part}_args" "${CMAKE_BINARY_DIR}/flash_${part}_args"
) )
endforeach() endforeach()

View File

@ -10,38 +10,43 @@ set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE})
set(ESPTOOLPY_SERIAL "${ESPTOOLPY}" --port "${ESPPORT}" --baud ${ESPBAUD}) set(ESPTOOLPY_SERIAL "${ESPTOOLPY}" --port "${ESPPORT}" --baud ${ESPBAUD})
set(ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS --flash_mode ${ESPFLASHMODE} --flash_freq ${ESPFLASHFREQ} --flash_size ${ESPFLASHSIZE}) set(ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS
--flash_mode ${ESPFLASHMODE}
--flash_freq ${ESPFLASHFREQ}
--flash_size ${ESPFLASHSIZE}
)
if(CONFIG_ESPTOOLPY_FLASHSIZE_DETECT) if(CONFIG_ESPTOOLPY_FLASHSIZE_DETECT)
# Set ESPFLASHSIZE to 'detect' *after* elf2image options are generated, # Set ESPFLASHSIZE to 'detect' *after* elf2image options are generated,
# as elf2image can't have 'detect' as an option... # as elf2image can't have 'detect' as an option...
set(ESPFLASHSIZE detect) set(ESPFLASHSIZE detect)
endif() endif()
# Set variables if the PHY data partition is in the flash # Set variables if the PHY data partition is in the flash
if (CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION) if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION)
set(PHY_PARTITION_OFFSET ${CONFIG_PHY_DATA_OFFSET}) set(PHY_PARTITION_OFFSET ${CONFIG_PHY_DATA_OFFSET})
set(PHY_PARTITION_BIN_FILE "esp32/phy_init_data.bin") set(PHY_PARTITION_BIN_FILE "esp32/phy_init_data.bin")
endif() endif()
# #
# Add 'app.bin' target - generates with elf2image # Add 'app.bin' target - generates with elf2image
# #
add_custom_command(OUTPUT "${PROJECT_NAME}.bin" add_custom_command(OUTPUT "${PROJECT_NAME}.bin"
COMMAND ${ESPTOOLPY} elf2image ${ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS} -o "${PROJECT_NAME}.bin" "${PROJECT_NAME}.elf" COMMAND ${ESPTOOLPY} elf2image ${ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS} -o "${PROJECT_NAME}.bin" "${PROJECT_NAME}.elf"
DEPENDS ${PROJECT_NAME}.elf DEPENDS ${PROJECT_NAME}.elf
VERBATIM VERBATIM
) )
add_custom_target(app ALL DEPENDS "${PROJECT_NAME}.bin") add_custom_target(app ALL DEPENDS "${PROJECT_NAME}.bin")
# #
# Add 'flash' target - not all build systems can run this directly # Add 'flash' target - not all build systems can run this directly
# #
function(esptool_py_custom_target target_name flasher_filename dependencies) function(esptool_py_custom_target target_name flasher_filename dependencies)
add_custom_target(${target_name} DEPENDS ${dependencies} add_custom_target(${target_name} DEPENDS ${dependencies}
COMMAND ${ESPTOOLPY} -p ${CONFIG_ESPTOOLPY_PORT} -b ${CONFIG_ESPTOOLPY_BAUD} write_flash @flash_${flasher_filename}_args COMMAND ${ESPTOOLPY} -p ${CONFIG_ESPTOOLPY_PORT} -b ${CONFIG_ESPTOOLPY_BAUD}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} write_flash @flash_${flasher_filename}_args
) WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
endfunction() endfunction()
esptool_py_custom_target(flash project "app;partition_table;bootloader") esptool_py_custom_target(flash project "app;partition_table;bootloader")

View File

@ -7,7 +7,7 @@ component_compile_definitions(HAVE_EXPAT_CONFIG_H)
# patch around warnings in third-party files # patch around warnings in third-party files
set_source_files_properties( set_source_files_properties(
library/xmlparse.c library/xmlparse.c
PROPERTIES COMPILE_FLAGS PROPERTIES COMPILE_FLAGS
-Wno-unused-function -Wno-unused-function
) )

View File

@ -1,7 +1,7 @@
set(COMPONENT_SRCS heap_caps_init.c heap_caps.c multi_heap.c heap_trace.c) set(COMPONENT_SRCS heap_caps_init.c heap_caps.c multi_heap.c heap_trace.c)
if(NOT CONFIG_HEAP_POISONING_DISABLED) if(NOT CONFIG_HEAP_POISONING_DISABLED)
set(COMPONENT_SRCS ${COMPONENT_SRCS} multi_heap_poisoning.c) set(COMPONENT_SRCS ${COMPONENT_SRCS} multi_heap_poisoning.c)
endif() endif()
set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_ADD_INCLUDEDIRS "include")
@ -9,11 +9,11 @@ set(COMPONENT_ADD_INCLUDEDIRS "include")
register_component() register_component()
if(CONFIG_HEAP_TRACING) if(CONFIG_HEAP_TRACING)
set(WRAP_FUNCTIONS set(WRAP_FUNCTIONS
calloc malloc free realloc heap_caps_malloc heap_caps_free heap_caps_realloc) calloc malloc free realloc heap_caps_malloc heap_caps_free heap_caps_realloc)
foreach(wrap ${WRAP_FUNCTIONS}) foreach(wrap ${WRAP_FUNCTIONS})
target_link_libraries(heap "-Wl,--wrap=${wrap}") target_link_libraries(heap "-Wl,--wrap=${wrap}")
endforeach() endforeach()
endif(CONFIG_HEAP_TRACING) endif()

View File

@ -1,70 +1,70 @@
set(SRC libsodium/src/libsodium) set(SRC libsodium/src/libsodium)
set(COMPONENT_SRCDIRS set(COMPONENT_SRCDIRS
port port
# Derived from libsodium/src/libsodium/Makefile.am # Derived from libsodium/src/libsodium/Makefile.am
# (ignoring the !MINIMAL set) # (ignoring the !MINIMAL set)
${SRC}/crypto_aead/chacha20poly1305/sodium ${SRC}/crypto_aead/chacha20poly1305/sodium
${SRC}/crypto_aead/xchacha20poly1305/sodium ${SRC}/crypto_aead/xchacha20poly1305/sodium
${SRC}/crypto_auth ${SRC}/crypto_auth
${SRC}/crypto_auth/hmacsha256 ${SRC}/crypto_auth/hmacsha256
${SRC}/crypto_auth/hmacsha512 ${SRC}/crypto_auth/hmacsha512
${SRC}/crypto_auth/hmacsha512256 ${SRC}/crypto_auth/hmacsha512256
${SRC}/crypto_box ${SRC}/crypto_box
${SRC}/crypto_box/curve25519xsalsa20poly1305 ${SRC}/crypto_box/curve25519xsalsa20poly1305
${SRC}/crypto_core/curve25519/ref10 ${SRC}/crypto_core/curve25519/ref10
${SRC}/crypto_core/hchacha20 ${SRC}/crypto_core/hchacha20
${SRC}/crypto_core/hsalsa20/ref2 ${SRC}/crypto_core/hsalsa20/ref2
${SRC}/crypto_core/hsalsa20 ${SRC}/crypto_core/hsalsa20
${SRC}/crypto_core/salsa/ref ${SRC}/crypto_core/salsa/ref
${SRC}/crypto_generichash ${SRC}/crypto_generichash
${SRC}/crypto_generichash/blake2b ${SRC}/crypto_generichash/blake2b
${SRC}/crypto_generichash/blake2b/ref ${SRC}/crypto_generichash/blake2b/ref
${SRC}/crypto_hash ${SRC}/crypto_hash
${SRC}/crypto_hash/sha256 ${SRC}/crypto_hash/sha256
${SRC}/crypto_hash/sha512 ${SRC}/crypto_hash/sha512
${SRC}/crypto_kdf/blake2b ${SRC}/crypto_kdf/blake2b
${SRC}/crypto_kdf ${SRC}/crypto_kdf
${SRC}/crypto_kx ${SRC}/crypto_kx
${SRC}/crypto_onetimeauth ${SRC}/crypto_onetimeauth
${SRC}/crypto_onetimeauth/poly1305 ${SRC}/crypto_onetimeauth/poly1305
${SRC}/crypto_onetimeauth/poly1305/donna ${SRC}/crypto_onetimeauth/poly1305/donna
${SRC}/crypto_pwhash/argon2 ${SRC}/crypto_pwhash/argon2
${SRC}/crypto_pwhash ${SRC}/crypto_pwhash
${SRC}/crypto_pwhash/scryptsalsa208sha256 ${SRC}/crypto_pwhash/scryptsalsa208sha256
${SRC}/crypto_pwhash/scryptsalsa208sha256/nosse ${SRC}/crypto_pwhash/scryptsalsa208sha256/nosse
${SRC}/crypto_scalarmult ${SRC}/crypto_scalarmult
${SRC}/crypto_scalarmult/curve25519 ${SRC}/crypto_scalarmult/curve25519
${SRC}/crypto_scalarmult/curve25519/ref10 ${SRC}/crypto_scalarmult/curve25519/ref10
${SRC}/crypto_secretbox ${SRC}/crypto_secretbox
${SRC}/crypto_secretbox/xsalsa20poly1305 ${SRC}/crypto_secretbox/xsalsa20poly1305
${SRC}/crypto_shorthash ${SRC}/crypto_shorthash
${SRC}/crypto_shorthash/siphash24 ${SRC}/crypto_shorthash/siphash24
${SRC}/crypto_shorthash/siphash24/ref ${SRC}/crypto_shorthash/siphash24/ref
${SRC}/crypto_sign ${SRC}/crypto_sign
${SRC}/crypto_sign/ed25519 ${SRC}/crypto_sign/ed25519
${SRC}/crypto_sign/ed25519/ref10 ${SRC}/crypto_sign/ed25519/ref10
${SRC}/crypto_stream/chacha20 ${SRC}/crypto_stream/chacha20
${SRC}/crypto_stream/chacha20/ref ${SRC}/crypto_stream/chacha20/ref
${SRC}/crypto_stream ${SRC}/crypto_stream
${SRC}/crypto_stream/salsa20 ${SRC}/crypto_stream/salsa20
${SRC}/crypto_stream/salsa20/ref ${SRC}/crypto_stream/salsa20/ref
${SRC}/crypto_stream/xsalsa20 ${SRC}/crypto_stream/xsalsa20
${SRC}/crypto_verify/sodium ${SRC}/crypto_verify/sodium
${SRC}/randombytes ${SRC}/randombytes
${SRC}/sodium ${SRC}/sodium
) )
if(CONFIG_LIBSODIUM_USE_MBEDTLS_SHA) if(CONFIG_LIBSODIUM_USE_MBEDTLS_SHA)
set(COMPONENT_SRCDIRS ${COMPONENT_SRCDIRS} set(COMPONENT_SRCDIRS ${COMPONENT_SRCDIRS}
port/crypto_hash_mbedtls port/crypto_hash_mbedtls
) )
else() else()
set(COMPONENT_SRCDIRS ${COMPONENT_SRCDIRS} set(COMPONENT_SRCDIRS ${COMPONENT_SRCDIRS}
${SRC}/crypto_hash/sha256/cp ${SRC}/crypto_hash/sha256/cp
${SRC}/crypto_hash/sha512/cp ${SRC}/crypto_hash/sha512/cp
) )
endif() endif()
set(COMPONENT_ADD_INCLUDEDIRS ${SRC}/include port_include) set(COMPONENT_ADD_INCLUDEDIRS ${SRC}/include port_include)
@ -73,28 +73,26 @@ set(COMPONENT_PRIV_INCLUDEDIRS ${SRC}/include/sodium port_include/sodium port)
register_component() register_component()
component_compile_definitions( component_compile_definitions(
CONFIGURED CONFIGURED
NATIVE_LITTLE_ENDIAN NATIVE_LITTLE_ENDIAN
HAVE_WEAK_SYMBOLS HAVE_WEAK_SYMBOLS
__STDC_LIMIT_MACROS __STDC_LIMIT_MACROS
__STDC_CONSTANT_MACROS __STDC_CONSTANT_MACROS
) )
component_compile_options(-Wno-unknown-pragmas) component_compile_options(-Wno-unknown-pragmas)
# patch around warnings in third-party files # patch around warnings in third-party files
set_source_files_properties( set_source_files_properties(
${SRC}/crypto_pwhash/argon2/argon2-fill-block-ref.c ${SRC}/crypto_pwhash/argon2/argon2-fill-block-ref.c
${SRC}/crypto_pwhash/argon2/pwhash_argon2i.c ${SRC}/crypto_pwhash/argon2/pwhash_argon2i.c
${SRC}/crypto_pwhash/argon2/argon2-core.c ${SRC}/crypto_pwhash/argon2/argon2-core.c
${SRC}/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c ${SRC}/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c
PROPERTIES COMPILE_FLAGS PROPERTIES COMPILE_FLAGS
-Wno-type-limits -Wno-type-limits
) )
set_source_files_properties( set_source_files_properties(
${SRC}/sodium/utils.c ${SRC}/sodium/utils.c
PROPERTIES COMPILE_FLAGS PROPERTIES COMPILE_FLAGS
-Wno-unused-variable -Wno-unused-variable
) )

View File

@ -1,20 +1,20 @@
set(COMPONENT_ADD_INCLUDEDIRS set(COMPONENT_ADD_INCLUDEDIRS
include/lwip include/lwip
include/lwip/port include/lwip/port
include/lwip/posix include/lwip/posix
apps/ping apps/ping
) )
if(CONFIG_PPP_SUPPORT) if(CONFIG_PPP_SUPPORT)
set(LWIP_PPP_DIRS netif/ppp/polarssl netif/ppp) set(LWIP_PPP_DIRS netif/ppp/polarssl netif/ppp)
endif() endif()
set(COMPONENT_SRCDIRS set(COMPONENT_SRCDIRS
api api
apps apps/sntp apps/ping apps apps/sntp apps/ping
core core/ipv4 core/ipv6 core core/ipv4 core/ipv6
${LWIP_PPP_DIRS} netif ${LWIP_PPP_DIRS} netif
port/freertos port/netif port/debug port) port/freertos port/netif port/debug port)
register_component() register_component()
@ -22,14 +22,14 @@ component_compile_options(-Wno-address)
# patch around warnings in third-party files # patch around warnings in third-party files
set_source_files_properties(api/tcpip.c set_source_files_properties(api/tcpip.c
PROPERTIES COMPILE_FLAGS PROPERTIES COMPILE_FLAGS
-Wno-unused-variable -Wno-unused-variable
) )
set_source_files_properties(core/pbuf.c core/tcp_in.c set_source_files_properties(core/pbuf.c core/tcp_in.c
PROPERTIES COMPILE_FLAGS PROPERTIES COMPILE_FLAGS
-Wno-unused-but-set-variable -Wno-unused-but-set-variable
) )
set_source_files_properties(apps/dhcpserver.c set_source_files_properties(apps/dhcpserver.c
PROPERTIES COMPILE_FLAGS PROPERTIES COMPILE_FLAGS
"-Wno-unused-variable -Wno-unused-but-set-variable -Wno-type-limits" "-Wno-unused-variable -Wno-unused-but-set-variable -Wno-type-limits"
) )

View File

@ -4,5 +4,5 @@ set(COMPONENT_SRCDIRS library port)
register_component() register_component()
target_compile_definitions(mbedtls PUBLIC target_compile_definitions(mbedtls PUBLIC
-DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h"
) )

View File

@ -2,18 +2,18 @@ set(COMPONENT_SRCDIRS ".")
set(COMPONENT_ADD_INCLUDEDIRS platform_include include) set(COMPONENT_ADD_INCLUDEDIRS platform_include include)
if(CONFIG_SPIRAM_CACHE_WORKAROUND) if(CONFIG_SPIRAM_CACHE_WORKAROUND)
set(LIBC c-psram-workaround) set(LIBC c-psram-workaround)
set(LIBM m-psram-workaround) set(LIBM m-psram-workaround)
else() else()
if(CONFIG_NEWLIB_NANO_FORMAT) if(CONFIG_NEWLIB_NANO_FORMAT)
set(LIBC c_nano) set(LIBC c_nano)
else() else()
set(LIBC c) set(LIBC c)
endif(CONFIG_NEWLIB_NANO_FORMAT) endif()
set(LIBM m) set(LIBM m)
endif(CONFIG_SPIRAM_CACHE_WORKAROUND) endif()
register_component() register_component()

View File

@ -3,21 +3,21 @@ set(partition_table_offset 0x8000)
# Set partition_csv to the configured partition source file # Set partition_csv to the configured partition source file
# #
if(CONFIG_PARTITION_TABLE_CUSTOM) if(CONFIG_PARTITION_TABLE_CUSTOM)
# Custom filename expands any path relative to the project # Custom filename expands any path relative to the project
get_filename_component(partition_csv "${CONFIG_PARTITION_TABLE_CUSTOM}" ABSOLUTE BASE_DIR "${PROJECT_PATH}") get_filename_component(partition_csv "${CONFIG_PARTITION_TABLE_CUSTOM}" ABSOLUTE BASE_DIR "${PROJECT_PATH}")
else() else()
# Other .csv files are always in the component directory # Other .csv files are always in the component directory
set(partition_csv "${CMAKE_CURRENT_SOURCE_DIR}/${CONFIG_PARTITION_TABLE_FILENAME}") set(partition_csv "${CMAKE_CURRENT_SOURCE_DIR}/${CONFIG_PARTITION_TABLE_FILENAME}")
endif() endif()
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES) if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
set(unsigned_partition_bin "partition-table-unsigned.bin") set(unsigned_partition_bin "partition-table-unsigned.bin")
set(final_partition_bin "partition-table.bin") set(final_partition_bin "partition-table.bin")
set(final_partition_target "sign_partition_table") set(final_partition_target "sign_partition_table")
else() else()
set(unsigned_partition_bin "partition-table.bin") set(unsigned_partition_bin "partition-table.bin")
set(final_partition_bin "partition-table.bin") set(final_partition_bin "partition-table.bin")
set(final_partition_target "build_partition_table") set(final_partition_target "build_partition_table")
endif() endif()
if(CONFIG_PARTITION_TABLE_MD5) if(CONFIG_PARTITION_TABLE_MD5)
@ -36,18 +36,24 @@ add_custom_command(OUTPUT "${unsigned_partition_bin}"
# Add signing steps # Add signing steps
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES) if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
get_filename_component(secure_boot_signing_key "${CONFIG_SECURE_BOOT_SIGNING_KEY}" ABSOLUTE BASE_DIR "${PROJECT_PATH}") get_filename_component(secure_boot_signing_key
"${CONFIG_SECURE_BOOT_SIGNING_KEY}"
ABSOLUTE BASE_DIR "${PROJECT_PATH}")
add_custom_command(OUTPUT "${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}" COMMAND "${PYTHON}" "${ESPSECUREPY}" sign_data --keyfile "${secure_boot_signing_key}"
DEPENDS "${unsigned_partition_bin}" -o "${final_partition_bin}" "${unsigned_partition_bin}"
VERBATIM) DEPENDS "${unsigned_partition_bin}"
VERBATIM)
endif() endif()
add_custom_target(partition_table ALL DEPENDS "${final_partition_bin}") 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 # Use global properties ESPTOOL_WRITE_FLASH_ARGS to pass this info to build
set_property(GLOBAL APPEND_STRING PROPERTY ESPTOOL_WRITE_FLASH_ARGS "${partition_table_offset} ${final_partition_bin} ") # the 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() register_config_only_component()

View File

@ -1,9 +1,9 @@
if(BOOTLOADER_BUILD) if(BOOTLOADER_BUILD)
# Bootloader needs SPIUnlock from this file, but doesn't # Bootloader needs SPIUnlock from this file, but doesn't
# need other parts of this component # need other parts of this component
set(COMPONENT_SRCS spi_flash_rom_patch.c) set(COMPONENT_SRCS spi_flash_rom_patch.c)
else() else()
set(COMPONENT_SRCDIRS .) set(COMPONENT_SRCDIRS .)
endif() endif()
set(COMPONENT_ADD_INCLUDEDIRS include) set(COMPONENT_ADD_INCLUDEDIRS include)

View File

@ -564,7 +564,7 @@ the esp-idf build system entirely by using a CMake feature called ExternalProjec
# External build process for quirc, runs in source dir and # External build process for quirc, runs in source dir and
# produces libquirc.a # produces libquirc.a
ExternalProject_Add(quirc_build externalproject_add(quirc_build
PREFIX ${COMPONENT_PATH} PREFIX ${COMPONENT_PATH}
SOURCE_DIR ${COMPONENT_PATH}/quirc SOURCE_DIR ${COMPONENT_PATH}/quirc
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
@ -588,10 +588,10 @@ the esp-idf build system entirely by using a CMake feature called ExternalProjec
(The above CMakeLists.txt can be used to create a component named ``quirc`` that builds the quirc_ project using its own Makefile.) (The above CMakeLists.txt can be used to create a component named ``quirc`` that builds the quirc_ project using its own Makefile.)
- ExternalProject_Add defines an external build system. - ``externalproject_add`` defines an external build system.
- ``SOURCE_DIR``, ``CONFIGURE_COMMAND``, ``BUILD_COMMAND`` and ``INSTALL_COMMAND`` should always be set. ``CONFIGURE_COMMAND`` can be set to an empty string if the build system has no "configure" step. ``INSTALL_COMMAND`` will generally be empty for ESP-IDF builds. - ``SOURCE_DIR``, ``CONFIGURE_COMMAND``, ``BUILD_COMMAND`` and ``INSTALL_COMMAND`` should always be set. ``CONFIGURE_COMMAND`` can be set to an empty string if the build system has no "configure" step. ``INSTALL_COMMAND`` will generally be empty for ESP-IDF builds.
- Setting ``BUILD_IN_SOURCE`` means the build directory is the same as the source directory. Otherwise you can set ``BUILD_DIR``. - Setting ``BUILD_IN_SOURCE`` means the build directory is the same as the source directory. Otherwise you can set ``BUILD_DIR``.
- Consult the ExternalProject_ documentation for more details about ``ExternalProject_Add()`` - Consult the ExternalProject_ documentation for more details about ``externalproject_add()``
- The second set of commands adds a library target, which points to the "imported" library file built by the external system. Some properties need to be set in order to add include directories and tell CMake where this file is. - The second set of commands adds a library target, which points to the "imported" library file built by the external system. Some properties need to be set in order to add include directories and tell CMake where this file is.
- Finally, the generated library is added to `ADDITIONAL_MAKE_CLEAN_FILES`_. This means ``make clean`` will delete this library. (Note that the other object files from the build won't be deleted.) - Finally, the generated library is added to `ADDITIONAL_MAKE_CLEAN_FILES`_. This means ``make clean`` will delete this library. (Note that the other object files from the build won't be deleted.)
@ -606,8 +606,8 @@ CMake has some unusual behaviour around external project builds:
- `ADDITIONAL_MAKE_CLEAN_FILES`_ only works when "make" is used as the build system. If Ninja_ or an IDE build system is used, it won't delete these files when cleaning. - `ADDITIONAL_MAKE_CLEAN_FILES`_ only works when "make" is used as the build system. If Ninja_ or an IDE build system is used, it won't delete these files when cleaning.
- However, the ExternalProject_ configure & build commands will *always* be re-run after a clean is run. - However, the ExternalProject_ configure & build commands will *always* be re-run after a clean is run.
- Therefore, there are two alternative recommended ways to configure the external build command: - Therefore, there are two alternative recommended ways to configure the external build command:
1. Have the external ``BUILD_COMMAND`` run a full clean compile of all sources. The build command will be run if any of the dependencies passed to ``ExternalProject_Add`` with ``DEPENDS`` have changed, or if this is a clean build (ie any of ``idf.py clean``, ``ninja clean``, or ``make clean`` was run.) 1. Have the external ``BUILD_COMMAND`` run a full clean compile of all sources. The build command will be run if any of the dependencies passed to ``externalproject_add`` with ``DEPENDS`` have changed, or if this is a clean build (ie any of ``idf.py clean``, ``ninja clean``, or ``make clean`` was run.)
2. Have the external ``BUILD_COMMAND`` be an incremental build command. Pass the parameter ``BUILD_ALWAYS 1`` to ``ExternalProject_Add``. This means the external project will be built each time a build is run, regardless of dependencies. This is only recommended if the external project has correct incremental build behaviour, and doesn't take too long to run. 2. Have the external ``BUILD_COMMAND`` be an incremental build command. Pass the parameter ``BUILD_ALWAYS 1`` to ``externalproject_add``. This means the external project will be built each time a build is run, regardless of dependencies. This is only recommended if the external project has correct incremental build behaviour, and doesn't take too long to run.
The best of these approaches for building an external project will depend on the project itself, its build system, and whether you anticipate needing to frequently recompile the project. The best of these approaches for building an external project will depend on the project itself, its build system, and whether you anticipate needing to frequently recompile the project.

View File

@ -170,6 +170,19 @@ To re-format a file, run::
tools/format.sh components/my_component/file.c tools/format.sh components/my_component/file.c
CMake Code Style
----------------
- Indent with four spaces.
- Maximum line length 120 characters. When splitting lines, try to
focus on readability where possible (for example, by pairing up
keyword/argument pairs on individual lines).
- Don't put anything in the optional parentheses after ``endforeach()``, ``endif()``, etc.
- Use lowercase (``with_underscores``) for command, function, and macro names.
- For locally scoped variables, use lowercase (``with_underscores``).
- For globally scoped variables, use uppercase (``WITH_UNDERSCORES``).
- Otherwise follow the defaults of the cmake-lint_ project.
Configuring the code style for a project using EditorConfig Configuring the code style for a project using EditorConfig
----------------------------------------------------------- -----------------------------------------------------------
@ -194,4 +207,3 @@ Language features
To be written. To be written.
.. _cmake-lint: https://github.com/richq/cmake-lint .. _cmake-lint: https://github.com/richq/cmake-lint

View File

@ -1,5 +1,5 @@
# The following five lines of boilerplate have to be in your project's CMakeLists # The following five lines of boilerplate have to be in your project's
# in this exact order for cmake to work correctly # CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
set(MAIN_SRCS main/hello_world_main.c) set(MAIN_SRCS main/hello_world_main.c)

View File

@ -5,170 +5,174 @@
# component_paths contains only unique component names. Directories # component_paths contains only unique component names. Directories
# earlier in the component_dirs list take precedence. # earlier in the component_dirs list take precedence.
function(components_find_all component_dirs filter_names component_paths component_names) function(components_find_all component_dirs filter_names component_paths component_names)
# component_dirs entries can be files or lists of files # component_dirs entries can be files or lists of files
set(paths "") set(paths "")
set(names "") set(names "")
# start by expanding the component_dirs list with all subdirectories # start by expanding the component_dirs list with all subdirectories
foreach(dir ${component_dirs}) foreach(dir ${component_dirs})
# Iterate any subdirectories for values # Iterate any subdirectories for values
file(GLOB subdirs LIST_DIRECTORIES true "${dir}/*") file(GLOB subdirs LIST_DIRECTORIES true "${dir}/*")
foreach(subdir ${subdirs}) foreach(subdir ${subdirs})
set(component_dirs "${component_dirs};${subdir}") set(component_dirs "${component_dirs};${subdir}")
endforeach()
endforeach() endforeach()
endforeach()
# Look for a component in each component_dirs entry # Look for a component in each component_dirs entry
foreach(dir ${component_dirs}) foreach(dir ${component_dirs})
file(GLOB component "${dir}/CMakeLists.txt") file(GLOB component "${dir}/CMakeLists.txt")
if(component) if(component)
get_filename_component(component "${component}" DIRECTORY) get_filename_component(component "${component}" DIRECTORY)
get_filename_component(name "${component}" NAME) get_filename_component(name "${component}" NAME)
if(NOT filter_names OR (name IN_LIST filter_names)) if(NOT filter_names OR (name IN_LIST filter_names))
if(NOT name IN_LIST names) if(NOT name IN_LIST names)
set(names "${names};${name}") set(names "${names};${name}")
set(paths "${paths};${component}") set(paths "${paths};${component}")
endif()
endif()
else() # no CMakeLists.txt file
# test for legacy component.mk and warn
file(GLOB legacy_component "${dir}/component.mk")
if(legacy_component)
get_filename_component(legacy_component "${legacy_component}" DIRECTORY)
message(WARNING "Component ${legacy_component} contains old-style component.mk but no CMakeLists.txt. "
"Component will be skipped.")
endif()
endif() endif()
endif()
else() # no CMakeLists.txt file endforeach()
# test for legacy component.mk and warn
file(GLOB legacy_component "${dir}/component.mk")
if(legacy_component)
get_filename_component(legacy_component "${legacy_component}" DIRECTORY)
message(WARNING "Component ${legacy_component} contains old-style component.mk but no CMakeLists.txt. Component will be skipped.")
endif()
endif(component)
endforeach(dir ${component_dirs}) set(${component_paths} ${paths} PARENT_SCOPE)
set(${component_names} ${names} PARENT_SCOPE)
set(${component_paths} ${paths} PARENT_SCOPE) endfunction()
set(${component_names} ${names} PARENT_SCOPE)
endfunction(components_find_all)
# Add a component to the build, using the COMPONENT variables defined # Add a component to the build, using the COMPONENT variables defined
# in the parent # in the parent
# #
function(register_component) function(register_component)
get_filename_component(component_dir ${CMAKE_CURRENT_LIST_FILE} DIRECTORY) get_filename_component(component_dir ${CMAKE_CURRENT_LIST_FILE} DIRECTORY)
get_filename_component(component ${component_dir} NAME) get_filename_component(component ${component_dir} NAME)
spaces2list(COMPONENT_SRCDIRS) spaces2list(COMPONENT_SRCDIRS)
spaces2list(COMPONENT_ADD_INCLUDEDIRS) spaces2list(COMPONENT_ADD_INCLUDEDIRS)
# Add to COMPONENT_SRCS by globbing in COMPONENT_SRCDIRS # Add to COMPONENT_SRCS by globbing in COMPONENT_SRCDIRS
if(NOT COMPONENT_SRCS) if(NOT COMPONENT_SRCS)
foreach(dir ${COMPONENT_SRCDIRS}) foreach(dir ${COMPONENT_SRCDIRS})
get_filename_component(abs_dir ${dir} ABSOLUTE BASE_DIR ${component_dir}) get_filename_component(abs_dir ${dir} ABSOLUTE BASE_DIR ${component_dir})
if(NOT IS_DIRECTORY ${abs_dir}) if(NOT IS_DIRECTORY ${abs_dir})
message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_SRCDIRS entry '${dir}' does not exist") message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_SRCDIRS entry '${dir}' does not exist")
endif() endif()
file(GLOB matches "${abs_dir}/*.c" "${abs_dir}/*.cpp" "${abs_dir}/*.S") file(GLOB matches "${abs_dir}/*.c" "${abs_dir}/*.cpp" "${abs_dir}/*.S")
if(matches) if(matches)
list(SORT matches) list(SORT matches)
set(COMPONENT_SRCS "${COMPONENT_SRCS};${matches}") set(COMPONENT_SRCS "${COMPONENT_SRCS};${matches}")
else() else()
message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_SRCDIRS entry '${dir}' contains no source files") message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_SRCDIRS entry '${dir}' has no source files")
endif(matches) endif()
endforeach() endforeach()
endif() endif()
# add public includes from other components when building this component # add public includes from other components when building this component
if(COMPONENT_SRCS OR embed_binaries) if(COMPONENT_SRCS OR embed_binaries)
add_library(${component} STATIC ${COMPONENT_SRCS}) add_library(${component} STATIC ${COMPONENT_SRCS})
set(include_type PUBLIC) 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)
foreach(embed_data ${COMPONENT_EMBED_FILES} ${COMPONENT_EMBED_TXTFILES})
if (embed_data IN_LIST COMPONENT_EMBED_TXTFILES)
set(embed_type "TEXT")
else() else()
set(embed_type "BINARY") add_library(${component} INTERFACE) # header-only component
endif() set(include_type INTERFACE)
target_add_binary_data("${component}" "${embed_data}" "${embed_type}")
endforeach()
# add public includes
foreach(include_dir ${COMPONENT_ADD_INCLUDEDIRS})
get_filename_component(abs_dir ${include_dir} ABSOLUTE BASE_DIR ${component_dir})
if(NOT IS_DIRECTORY ${abs_dir})
message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_ADD_INCLUDEDIRS entry '${include_dir}' does not exist")
endif()
target_include_directories(${component} ${include_type} ${abs_dir})
endforeach()
# add private includes
foreach(include_dir ${COMPONENT_PRIV_INCLUDEDIRS})
if (${include_type} STREQUAL INTERFACE)
message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE} sets no component source files but sets COMPONENT_PRIV_INCLUDEDIRS")
endif() endif()
get_filename_component(abs_dir ${include_dir} ABSOLUTE BASE_DIR ${component_dir}) # binaries to embed directly in library
if(NOT IS_DIRECTORY ${abs_dir}) spaces2list(COMPONENT_EMBED_FILES)
message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_PRIV_INCLUDEDIRS entry '${niclude_dir}' does not exist") spaces2list(COMPONENT_EMBED_TXTFILES)
endif() foreach(embed_data ${COMPONENT_EMBED_FILES} ${COMPONENT_EMBED_TXTFILES})
target_include_directories(${component} PRIVATE ${abs_dir}) if(embed_data IN_LIST COMPONENT_EMBED_TXTFILES)
endforeach() set(embed_type "TEXT")
else()
set(embed_type "BINARY")
endif()
target_add_binary_data("${component}" "${embed_data}" "${embed_type}")
endforeach()
endfunction(register_component) # add public includes
foreach(include_dir ${COMPONENT_ADD_INCLUDEDIRS})
get_filename_component(abs_dir ${include_dir} ABSOLUTE BASE_DIR ${component_dir})
if(NOT IS_DIRECTORY ${abs_dir})
message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: "
"COMPONENT_ADD_INCLUDEDIRS entry '${include_dir}' not found")
endif()
target_include_directories(${component} ${include_type} ${abs_dir})
endforeach()
# add private includes
foreach(include_dir ${COMPONENT_PRIV_INCLUDEDIRS})
if(${include_type} STREQUAL INTERFACE)
message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE} "
"sets no component source files but sets COMPONENT_PRIV_INCLUDEDIRS")
endif()
get_filename_component(abs_dir ${include_dir} ABSOLUTE BASE_DIR ${component_dir})
if(NOT IS_DIRECTORY ${abs_dir})
message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: "
"COMPONENT_PRIV_INCLUDEDIRS entry '${include_dir}' does not exist")
endif()
target_include_directories(${component} PRIVATE ${abs_dir})
endforeach()
endfunction()
function(register_config_only_component) function(register_config_only_component)
get_filename_component(component_dir ${CMAKE_CURRENT_LIST_FILE} DIRECTORY) get_filename_component(component_dir ${CMAKE_CURRENT_LIST_FILE} DIRECTORY)
get_filename_component(component ${component_dir} NAME) get_filename_component(component ${component_dir} NAME)
# No-op for now... # No-op for now...
endfunction(register_config_only_component) endfunction()
function(components_finish_registration) function(components_finish_registration)
# each component should see the include directories of each other # 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 # (we can't do this until all components are registered, because if(TARGET ...) won't work
foreach(a ${COMPONENTS} ${CMAKE_PROJECT_NAME}.elf) foreach(a ${COMPONENTS} ${CMAKE_PROJECT_NAME}.elf)
if (TARGET ${a}) if(TARGET ${a})
get_target_property(a_imported ${a} IMPORTED) get_target_property(a_imported ${a} IMPORTED)
get_target_property(a_type ${a} TYPE) get_target_property(a_type ${a} TYPE)
if (NOT a_imported) if(NOT a_imported)
if (${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE) if(${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
foreach(b ${COMPONENTS}) foreach(b ${COMPONENTS})
if (TARGET ${b} AND NOT ${a} STREQUAL ${b}) if(TARGET ${b} AND NOT ${a} STREQUAL ${b})
# Add all public compile options from b in a # Add all public compile options from b in a
target_include_directories(${a} PRIVATE target_include_directories(${a} PRIVATE
$<TARGET_PROPERTY:${b},INTERFACE_INCLUDE_DIRECTORIES>) $<TARGET_PROPERTY:${b},INTERFACE_INCLUDE_DIRECTORIES>)
target_compile_definitions(${a} PRIVATE target_compile_definitions(${a} PRIVATE
$<TARGET_PROPERTY:${b},INTERFACE_COMPILE_DEFINITIONS>) $<TARGET_PROPERTY:${b},INTERFACE_COMPILE_DEFINITIONS>)
target_compile_options(${a} PRIVATE target_compile_options(${a} PRIVATE
$<TARGET_PROPERTY:${b},INTERFACE_COMPILE_OPTIONS>) $<TARGET_PROPERTY:${b},INTERFACE_COMPILE_OPTIONS>)
endif()
endforeach(b)
endif()
endif() endif()
endforeach(b)
endif(${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
endif(NOT a_imported)
if (${a_type} MATCHES .+_LIBRARY) if(${a_type} MATCHES .+_LIBRARY)
set(COMPONENT_LIBRARIES "${COMPONENT_LIBRARIES};${a}") set(COMPONENT_LIBRARIES "${COMPONENT_LIBRARIES};${a}")
endif() endif()
endif() endif()
endforeach() endforeach()
# Embedded binary & text files # Embedded binary & text files
spaces2list(COMPONENT_EMBED_FILES) spaces2list(COMPONENT_EMBED_FILES)
foreach(embed_src ${COMPONENT_EMBED_FILES}) foreach(embed_src ${COMPONENT_EMBED_FILES})
target_add_binary_data(${component} "${embed_src}" BINARY) target_add_binary_data(${component} "${embed_src}" BINARY)
endforeach() endforeach()
spaces2list(COMPONENT_EMBED_TXTFILES) spaces2list(COMPONENT_EMBED_TXTFILES)
foreach(embed_src ${COMPONENT_EMBED_TXTFILES}) foreach(embed_src ${COMPONENT_EMBED_TXTFILES})
target_add_binary_data(${component} "${embed_src}" TEXT) target_add_binary_data(${component} "${embed_src}" TEXT)
endforeach() endforeach()
target_link_libraries(${CMAKE_PROJECT_NAME}.elf ${COMPONENT_LIBRARIES}) target_link_libraries(${CMAKE_PROJECT_NAME}.elf ${COMPONENT_LIBRARIES})
message(STATUS "Component libraries: ${COMPONENT_LIBRARIES}") message(STATUS "Component libraries: ${COMPONENT_LIBRARIES}")
endfunction(components_finish_registration) endfunction()

View File

@ -4,16 +4,17 @@
set(ctng_version_warning "Check Getting Started documentation or proceed at own risk.") set(ctng_version_warning "Check Getting Started documentation or proceed at own risk.")
function(gcc_version_check expected_gcc_version) function(gcc_version_check expected_gcc_version)
if(NOT "${CMAKE_C_COMPILER_VERSION}" STREQUAL "${expected_gcc_version}") if(NOT "${CMAKE_C_COMPILER_VERSION}" STREQUAL "${expected_gcc_version}")
message(WARNING "Xtensa toolchain ${CMAKE_C_COMPILER} version ${CMAKE_C_COMPILER_VERSION} is not the supported version ${expected_gcc_version}. ${ctng_version_warning}") message(WARNING "Xtensa toolchain ${CMAKE_C_COMPILER} version ${CMAKE_C_COMPILER_VERSION} "
endif() "is not the supported version ${expected_gcc_version}. ${ctng_version_warning}")
endif()
endfunction() endfunction()
function(crosstool_version_check expected_ctng_version) function(crosstool_version_check expected_ctng_version)
execute_process( execute_process(
COMMAND ${CMAKE_C_COMPILER} -v COMMAND ${CMAKE_C_COMPILER} -v
ERROR_VARIABLE toolchain_stderr ERROR_VARIABLE toolchain_stderr
OUTPUT_QUIET) OUTPUT_QUIET)
string(REGEX MATCH "crosstool-ng-[0-9a-g\\.-]+" ctng_version "${toolchain_stderr}") string(REGEX MATCH "crosstool-ng-[0-9a-g\\.-]+" ctng_version "${toolchain_stderr}")
string(REPLACE "crosstool-ng-" "" ctng_version "${ctng_version}") string(REPLACE "crosstool-ng-" "" ctng_version "${ctng_version}")

View File

@ -1,61 +1,61 @@
find_package(Git) find_package(Git)
if(NOT GIT_FOUND) if(NOT GIT_FOUND)
message(WARNING "Git executable was not found. Git submodule checks will not be executed. If you have any build issues at all, start by adding git executable to the PATH and rerun cmake to not see this warning again.") message(WARNING "Git executable was not found. Git submodule checks will not be executed. "
"If you have any build issues at all, start by adding git executable to the PATH and "
"rerun cmake to not see this warning again.")
function(git_submodule_check root_path) function(git_submodule_check root_path)
# no-op # no-op
endfunction() endfunction()
else(NOT GIT_FOUND) else()
function(git_submodule_check root_path) function(git_submodule_check root_path)
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule status
WORKING_DIRECTORY ${root_path}
OUTPUT_VARIABLE submodule_status
)
# git submodule status output not guaranteed to be stable,
# may need to check GIT_VERSION_STRING and do some fiddling in the
# future...
lines2list(submodule_status)
foreach(line ${submodule_status})
string(REGEX MATCH "(.)[0-9a-f]+ ([^\( ]+) ?" _ignored "${line}")
set(status "${CMAKE_MATCH_1}")
set(submodule_path "${CMAKE_MATCH_2}")
if("${status}" STREQUAL "-") # missing submodule
message(STATUS "Initialising new submodule ${submodule_path}...")
execute_process( execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive ${submodule_path} COMMAND ${GIT_EXECUTABLE} submodule status
WORKING_DIRECTORY ${root_path} WORKING_DIRECTORY ${root_path}
RESULT_VARIABLE git_result OUTPUT_VARIABLE submodule_status
) )
if(git_result)
message(FATAL_ERROR "Git submodule init failed for ${submodule_path}")
endif(git_result)
elseif(NOT "${status}" STREQUAL " ") # git submodule status output not guaranteed to be stable,
message(WARNING "Git submodule ${submodule_path} is out of date. Run 'git submodule update --init --recursive' to fix.") # may need to check GIT_VERSION_STRING and do some fiddling in the
endif() # future...
# Force a re-run of cmake if the submodule's .git file changes or is changed (ie accidental deinit) lines2list(submodule_status)
get_filename_component(submodule_abs_path ${submodule_path} ABSOLUTE BASE_DIR ${root_path})
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${submodule_abs_path}/.git)
# same if the HEAD file in the submodule's directory changes (ie commit changes). This will at least prit the 'out of date' warning
set(submodule_head "${root_path}/.git/modules/${submodule_path}/HEAD")
if(EXISTS "${submodule_head}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${submodule_head})
endif()
endforeach() foreach(line ${submodule_status})
endfunction(git_submodule_check) string(REGEX MATCH "(.)[0-9a-f]+ ([^\( ]+) ?" _ignored "${line}")
set(status "${CMAKE_MATCH_1}")
set(submodule_path "${CMAKE_MATCH_2}")
endif(NOT GIT_FOUND) if("${status}" STREQUAL "-") # missing submodule
message(STATUS "Initialising new submodule ${submodule_path}...")
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive ${submodule_path}
WORKING_DIRECTORY ${root_path}
RESULT_VARIABLE git_result
)
if(git_result)
message(FATAL_ERROR "Git submodule init failed for ${submodule_path}")
endif()
elseif(NOT "${status}" STREQUAL " ")
message(WARNING "Git submodule ${submodule_path} is out of date. "
"Run 'git submodule update --init --recursive' to fix.")
endif()
# Force a re-run of cmake if the submodule's .git file changes or is changed (ie accidental deinit)
get_filename_component(submodule_abs_path ${submodule_path} ABSOLUTE BASE_DIR ${root_path})
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${submodule_abs_path}/.git)
# same if the HEAD file in the submodule's directory changes (ie commit changes).
# This will at least print the 'out of date' warning
set(submodule_head "${root_path}/.git/modules/${submodule_path}/HEAD")
if(EXISTS "${submodule_head}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${submodule_head})
endif()
endforeach()
endfunction()
endif()

View File

@ -9,27 +9,27 @@ include(crosstool_version_check)
# loaded and the toolchain and project are not yet set # loaded and the toolchain and project are not yet set
# #
macro(idf_set_global_variables) macro(idf_set_global_variables)
# Note that CONFIG_xxx is not available when this function is called # Note that CONFIG_xxx is not available when this function is called
set_default(EXTRA_COMPONENT_DIRS "") set_default(EXTRA_COMPONENT_DIRS "")
# PROJECT_PATH has the path to the IDF project (top-level cmake directory) # PROJECT_PATH has the path to the IDF project (top-level cmake directory)
# #
# (cmake calls this CMAKE_SOURCE_DIR, keeping old name for compatibility.) # (cmake calls this CMAKE_SOURCE_DIR, keeping old name for compatibility.)
set(PROJECT_PATH "${CMAKE_SOURCE_DIR}") set(PROJECT_PATH "${CMAKE_SOURCE_DIR}")
# Note: "main" is no longer a component... # Note: "main" is no longer a component...
# #
set_default(COMPONENT_DIRS "${PROJECT_PATH}/components ${EXTRA_COMPONENT_DIRS} ${IDF_PATH}/components") set_default(COMPONENT_DIRS "${PROJECT_PATH}/components ${EXTRA_COMPONENT_DIRS} ${IDF_PATH}/components")
spaces2list(COMPONENT_DIRS) spaces2list(COMPONENT_DIRS)
spaces2list(COMPONENTS) spaces2list(COMPONENTS)
# Tell cmake to drop executables in the top-level build dir # Tell cmake to drop executables in the top-level build dir
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}") set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
# path to idf.py tool # path to idf.py tool
set(IDFTOOL ${PYTHON} "${IDF_PATH}/tools/idf.py") set(IDFTOOL ${PYTHON} "${IDF_PATH}/tools/idf.py")
endmacro() endmacro()
# Add all the IDF global compiler & preprocessor options # Add all the IDF global compiler & preprocessor options
@ -39,52 +39,63 @@ endmacro()
# don't call or edit this function. TODO DESCRIBE WHAT TO DO INSTEAD # don't call or edit this function. TODO DESCRIBE WHAT TO DO INSTEAD
# #
function(idf_set_global_compiler_options) function(idf_set_global_compiler_options)
add_definitions(-DESP_PLATFORM) add_definitions(-DESP_PLATFORM)
add_definitions(-DHAVE_CONFIG_H) add_definitions(-DHAVE_CONFIG_H)
if(CONFIG_OPTIMIZATION_LEVEL_RELEASE) if(CONFIG_OPTIMIZATION_LEVEL_RELEASE)
add_compile_options(-Os) add_compile_options(-Os)
else() else()
add_compile_options(-Og) add_compile_options(-Og)
endif()
add_c_compile_options(-std=gnu99)
add_cxx_compile_options(-std=gnu++11 -fno-rtti)
if(CONFIG_CXX_EXCEPTIONS)
add_cxx_compile_options(-fexceptions)
else()
add_cxx_compile_options(-fno-exceptions)
endif()
# Default compiler configuration
add_compile_options(-ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib)
# Default warnings configuration
add_compile_options(-Wall -Werror=all -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wextra -Wno-unused-parameter -Wno-sign-compare)
add_c_compile_options(-Wno-old-style-declaration)
# Stack protection
if(NOT BOOTLOADER_BUILD)
if(CONFIG_STACK_CHECK_NORM)
add_compile_options(-fstack-protector)
elseif(CONFIG_STACK_CHECK_STRONG)
add_compile_options(-fstack-protector-strong)
elseif(CONFIG_STACK_CHECK_ALL)
add_compile_options(-fstack-protector-all)
endif() endif()
endif()
if(CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED) add_c_compile_options(-std=gnu99)
add_definitions(-DNDEBUG)
endif()
# Always generate debug symbols (even in Release mode, these don't add_cxx_compile_options(-std=gnu++11 -fno-rtti)
# go into the final binary so have no impact on size)
add_compile_options(-ggdb)
add_compile_options("-I${CMAKE_BINARY_DIR}") # for sdkconfig.h if(CONFIG_CXX_EXCEPTIONS)
add_cxx_compile_options(-fexceptions)
else()
add_cxx_compile_options(-fno-exceptions)
endif()
# Default compiler configuration
add_compile_options(-ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib)
# Default warnings configuration
add_compile_options(
-Wall
-Werror=all
-Wno-error=unused-function
-Wno-error=unused-but-set-variable
-Wno-error=unused-variable
-Wno-error=deprecated-declarations
-Wextra
-Wno-unused-parameter
-Wno-sign-compare)
add_c_compile_options(
-Wno-old-style-declaration
)
# Stack protection
if(NOT BOOTLOADER_BUILD)
if(CONFIG_STACK_CHECK_NORM)
add_compile_options(-fstack-protector)
elseif(CONFIG_STACK_CHECK_STRONG)
add_compile_options(-fstack-protector-strong)
elseif(CONFIG_STACK_CHECK_ALL)
add_compile_options(-fstack-protector-all)
endif()
endif()
if(CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED)
add_definitions(-DNDEBUG)
endif()
# Always generate debug symbols (even in Release mode, these don't
# go into the final binary so have no impact on size)
add_compile_options(-ggdb)
add_compile_options("-I${CMAKE_BINARY_DIR}") # for sdkconfig.h
# Enable ccache if it's on the path # Enable ccache if it's on the path
find_program(CCACHE_FOUND ccache) find_program(CCACHE_FOUND ccache)
@ -93,27 +104,27 @@ function(idf_set_global_compiler_options)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
endif() endif()
endfunction(idf_set_global_compiler_options) endfunction()
# Verify the IDF environment is configured correctly (environment, toolchain, etc) # Verify the IDF environment is configured correctly (environment, toolchain, etc)
function(idf_verify_environment) function(idf_verify_environment)
if(NOT CMAKE_PROJECT_NAME) if(NOT CMAKE_PROJECT_NAME)
message(FATAL_ERROR "Internal error, IDF project.cmake should have set this variable already") message(FATAL_ERROR "Internal error, IDF project.cmake should have set this variable already")
endif() endif()
# Check toolchain is configured properly in cmake # Check toolchain is configured properly in cmake
if(NOT ( ${CMAKE_SYSTEM_NAME} STREQUAL "Generic" AND ${CMAKE_C_COMPILER} MATCHES xtensa)) if(NOT ( ${CMAKE_SYSTEM_NAME} STREQUAL "Generic" AND ${CMAKE_C_COMPILER} MATCHES xtensa))
message(FATAL_ERROR "Internal error, toolchain has not been set correctly by project") message(FATAL_ERROR "Internal error, toolchain has not been set correctly by project")
endif() endif()
# #
# Warn if the toolchain version doesn't match # Warn if the toolchain version doesn't match
# #
# TODO: make these platform-specific for diff toolchains # TODO: make these platform-specific for diff toolchains
gcc_version_check("5.2.0") gcc_version_check("5.2.0")
crosstool_version_check("1.22.0-80-g6c4433a") crosstool_version_check("1.22.0-80-g6c4433a")
endfunction() endfunction()
@ -123,62 +134,54 @@ endfunction()
# Adds .map & .bin file targets # Adds .map & .bin file targets
# Sets up flash-related targets # Sets up flash-related targets
function(idf_add_executable) function(idf_add_executable)
set(exe_target ${PROJECT_NAME}.elf) set(exe_target ${PROJECT_NAME}.elf)
spaces2list(MAIN_SRCS)
add_executable(${exe_target} "${MAIN_SRCS}")
add_map_file(${exe_target}) spaces2list(MAIN_SRCS)
add_executable(${exe_target} "${MAIN_SRCS}")
add_flasher_argfile(${exe_target}) add_map_file(${exe_target})
endfunction()
endfunction(idf_add_executable)
# add_map_file # add_map_file
# #
# Set linker args for 'exe_target' to generate a linker Map file # Set linker args for 'exe_target' to generate a linker Map file
function(add_map_file exe_target) function(add_map_file exe_target)
get_filename_component(basename ${exe_target} NAME_WE) get_filename_component(basename ${exe_target} NAME_WE)
set(mapfile "${basename}.map") set(mapfile "${basename}.map")
target_link_libraries(${exe_target} "-Wl,--gc-sections -Wl,--cref -Wl,--Map=${mapfile} -Wl,--start-group") 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}") set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
"${CMAKE_CURRENT_BINARY_DIR}/${mapfile}")
# add size targets, depend on map file, run idf_size.py # add size targets, depend on map file, run idf_size.py
add_custom_target(size add_custom_target(size
DEPENDS ${exe_target} DEPENDS ${exe_target}
COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py ${mapfile} COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py ${mapfile}
) )
add_custom_target(size-files add_custom_target(size-files
DEPENDS ${exe_target} DEPENDS ${exe_target}
COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py --files ${mapfile} COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py --files ${mapfile}
) )
add_custom_target(size-components add_custom_target(size-components
DEPENDS ${exe_target} DEPENDS ${exe_target}
COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py --archives ${mapfile} COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py --archives ${mapfile}
) )
endfunction(add_map_file) endfunction()
# add_flasher_argfile
#
# Add argument file(s) for flashing the app, and for flashing the whole system
function(add_flasher_argfile)
endfunction(add_flasher_argfile)
# component_compile_options # component_compile_options
# #
# Wrapper around target_compile_options that passes the component name # Wrapper around target_compile_options that passes the component name
function(component_compile_options) function(component_compile_options)
target_compile_options(${COMPONENT_NAME} PRIVATE ${ARGV}) target_compile_options(${COMPONENT_NAME} PRIVATE ${ARGV})
endfunction() endfunction()
# component_compile_definitions # component_compile_definitions
# #
# Wrapper around target_compile_definitions that passes the component name # Wrapper around target_compile_definitions that passes the component name
function(component_compile_definitions) function(component_compile_definitions)
target_compile_definitions(${COMPONENT_NAME} PRIVATE ${ARGV}) target_compile_definitions(${COMPONENT_NAME} PRIVATE ${ARGV})
endfunction() endfunction()
# idf_get_git_revision # idf_get_git_revision
@ -188,8 +191,8 @@ endfunction()
# Running git_describe() here automatically triggers rebuilds # Running git_describe() here automatically triggers rebuilds
# if the ESP-IDF git version changes # if the ESP-IDF git version changes
function(idf_get_git_revision) function(idf_get_git_revision)
git_describe(IDF_VER "${IDF_PATH}") git_describe(IDF_VER "${IDF_PATH}")
add_definitions(-DIDF_VER=\"${IDF_VER}\") add_definitions(-DIDF_VER=\"${IDF_VER}\")
git_submodule_check("${IDF_PATH}") git_submodule_check("${IDF_PATH}")
set(IDF_VER ${IDF_VER} PARENT_SCOPE) set(IDF_VER ${IDF_VER} PARENT_SCOPE)
endfunction() endfunction()

View File

@ -1,103 +1,106 @@
include(ExternalProject) include(ExternalProject)
macro(kconfig_set_variables) macro(kconfig_set_variables)
set(MCONF kconfig_bin/mconf) set(MCONF kconfig_bin/mconf)
set_default(SDKCONFIG ${PROJECT_PATH}/sdkconfig) set_default(SDKCONFIG ${PROJECT_PATH}/sdkconfig)
set(SDKCONFIG_HEADER ${CMAKE_BINARY_DIR}/sdkconfig.h) set(SDKCONFIG_HEADER ${CMAKE_BINARY_DIR}/sdkconfig.h)
set(SDKCONFIG_CMAKE ${CMAKE_BINARY_DIR}/sdkconfig.cmake) set(SDKCONFIG_CMAKE ${CMAKE_BINARY_DIR}/sdkconfig.cmake)
set(SDKCONFIG_JSON ${CMAKE_BINARY_DIR}/sdkconfig.json) set(SDKCONFIG_JSON ${CMAKE_BINARY_DIR}/sdkconfig.json)
set(ROOT_KCONFIG ${IDF_PATH}/Kconfig) set(ROOT_KCONFIG ${IDF_PATH}/Kconfig)
set_default(SDKCONFIG_DEFAULTS "${SDKCONFIG}.defaults") set_default(SDKCONFIG_DEFAULTS "${SDKCONFIG}.defaults")
endmacro() endmacro()
# Use the existing Makefile to build mconf (out of tree) when needed # Use the existing Makefile to build mconf (out of tree) when needed
# #
# TODO: Download(?) a prebuilt mingw mconf on Windows # TODO: Download(?) a prebuilt mingw mconf on Windows
ExternalProject_Add(mconf externalproject_add(mconf
SOURCE_DIR ${IDF_PATH}/tools/kconfig SOURCE_DIR ${IDF_PATH}/tools/kconfig
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BINARY_DIR "kconfig_bin" BINARY_DIR "kconfig_bin"
BUILD_COMMAND make -f ${IDF_PATH}/tools/kconfig/Makefile mconf BUILD_COMMAND make -f ${IDF_PATH}/tools/kconfig/Makefile mconf
BUILD_BYPRODUCTS ${MCONF} BUILD_BYPRODUCTS ${MCONF}
INSTALL_COMMAND "" INSTALL_COMMAND ""
EXCLUDE_FROM_ALL 1 EXCLUDE_FROM_ALL 1
) )
# Find all Kconfig files for all components # Find all Kconfig files for all components
function(kconfig_process_config) function(kconfig_process_config)
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/config") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/config")
set(kconfigs ) set(kconfigs)
set(kconfigs_projbuild ) set(kconfigs_projbuild)
# Find Kconfig and Kconfig.projbuild for each component as applicable # Find Kconfig and Kconfig.projbuild for each component as applicable
# if any of these change, cmake should rerun # if any of these change, cmake should rerun
foreach(dir ${COMPONENT_PATHS} "${CMAKE_SOURCE_DIR}/main") foreach(dir ${COMPONENT_PATHS} "${CMAKE_SOURCE_DIR}/main")
file(GLOB kconfig "${dir}/Kconfig") file(GLOB kconfig "${dir}/Kconfig")
if(kconfig) if(kconfig)
set(kconfigs "${kconfigs} ${kconfig}") set(kconfigs "${kconfigs} ${kconfig}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${kconfig}) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${kconfig})
endif()
file(GLOB kconfig ${dir}/Kconfig.projbuild)
if(kconfig)
set(kconfigs_projbuild "${kconfigs_projbuild} ${kconfig}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${kconfig})
endif()
endforeach()
if(EXISTS ${SDKCONFIG_DEFAULTS})
set(defaults_arg --defaults "${SDKCONFIG_DEFAULTS}")
endif() endif()
file(GLOB kconfig ${dir}/Kconfig.projbuild)
if(kconfig) set(confgen_basecommand
set(kconfigs_projbuild "${kconfigs_projbuild} ${kconfig}") ${PYTHON} ${IDF_PATH}/tools/kconfig_new/confgen.py
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${kconfig}) --kconfig ${ROOT_KCONFIG}
--config ${SDKCONFIG}
${defaults_arg}
--create-config-if-missing
--env "COMPONENT_KCONFIGS=${kconfigs}"
--env "COMPONENT_KCONFIGS_PROJBUILD=${kconfigs_projbuild}")
# Generate the menuconfig target (uses C-based mconf tool)
add_custom_target(menuconfig
DEPENDS mconf
# create any missing config file, with defaults if necessary
COMMAND ${confgen_basecommand} --output config ${SDKCONFIG}
COMMAND ${CMAKE_COMMAND} -E env
"COMPONENT_KCONFIGS=${kconfigs}"
"COMPONENT_KCONFIGS_PROJBUILD=${kconfigs_projbuild}"
"KCONFIG_CONFIG=${SDKCONFIG}"
${MCONF} ${ROOT_KCONFIG}
VERBATIM
USES_TERMINAL)
# Generate configuration output via confgen.py
# makes sdkconfig.h and skdconfig.cmake
#
# This happens during the cmake run not during the build
execute_process(COMMAND ${confgen_basecommand}
--output header ${SDKCONFIG_HEADER}
--output cmake ${SDKCONFIG_CMAKE}
--output json ${SDKCONFIG_JSON}
RESULT_VARIABLE config_result)
if(config_result)
message(FATAL_ERROR "Failed to run confgen.py (${confgen_basecommand}). Error ${config_result}")
endif() endif()
endforeach(dir ${COMPONENT_PATHS})
if(EXISTS ${SDKCONFIG_DEFAULTS}) # When sdkconfig file changes in the future, trigger a cmake run
set(defaults_arg --defaults "${SDKCONFIG_DEFAULTS}") set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${SDKCONFIG}")
endif()
set(confgen_basecommand # Ditto if either of the generated files are missing/modified (this is a bit irritating as it means
${PYTHON} ${IDF_PATH}/tools/kconfig_new/confgen.py # you can't edit these manually without them being regenerated, but I don't know of a better way...)
--kconfig ${ROOT_KCONFIG} set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${SDKCONFIG_HEADER}")
--config ${SDKCONFIG} set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${SDKCONFIG_CMAKE}")
${defaults_arg}
--create-config-if-missing
--env "COMPONENT_KCONFIGS=${kconfigs}"
--env "COMPONENT_KCONFIGS_PROJBUILD=${kconfigs_projbuild}")
# Generate the menuconfig target (uses C-based mconf tool) # Or if the config generation tool changes
add_custom_target(menuconfig set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${IDF_PATH}/tools/kconfig_new/confgen.py")
DEPENDS mconf set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${IDF_PATH}/tools/kconfig_new/kconfiglib.py")
COMMAND ${confgen_basecommand} --output config ${SDKCONFIG} # create any missing config file, with defaults if necessary
COMMAND ${CMAKE_COMMAND} -E env
"COMPONENT_KCONFIGS=${kconfigs}"
"COMPONENT_KCONFIGS_PROJBUILD=${kconfigs_projbuild}"
"KCONFIG_CONFIG=${SDKCONFIG}"
${MCONF} ${ROOT_KCONFIG}
VERBATIM
USES_TERMINAL)
# Generate configuration output via confgen.py set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
# makes sdkconfig.h and skdconfig.cmake ADDITIONAL_MAKE_CLEAN_FILES
# "${SDKCONFIG_HEADER}" "${SDKCONFIG_CMAKE}")
# This happens during the cmake run not during the build
execute_process(COMMAND ${confgen_basecommand}
--output header ${SDKCONFIG_HEADER}
--output cmake ${SDKCONFIG_CMAKE}
--output json ${SDKCONFIG_JSON}
RESULT_VARIABLE config_result)
if(config_result)
message(FATAL_ERROR "Failed to run confgen.py (${confgen_basecommand}). Error ${config_result}")
endif()
# When sdkconfig file changes in the future, trigger a cmake run
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${SDKCONFIG}")
# Ditto if either of the generated files are missing/modified (this is a bit irritating as it means
# you can't edit these manually without them being regenerated, but I don't know of a better way...)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${SDKCONFIG_HEADER}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${SDKCONFIG_CMAKE}")
# Or if the config generation tool changes
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${IDF_PATH}/tools/kconfig_new/confgen.py")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${IDF_PATH}/tools/kconfig_new/kconfiglib.py")
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${SDKCONFIG_HEADER}" "${SDKCONFIG_CMAKE}")
endfunction() endfunction()

View File

@ -5,16 +5,19 @@ cmake_minimum_required(VERSION 3.5)
# Set IDF_PATH, as nothing else will work without this # Set IDF_PATH, as nothing else will work without this
set(IDF_PATH "$ENV{IDF_PATH}") set(IDF_PATH "$ENV{IDF_PATH}")
if(NOT IDF_PATH) if(NOT IDF_PATH)
# Documentation says you should set IDF_PATH in your environment, but we # Documentation says you should set IDF_PATH in your environment, but we
# can infer it here if it's not set. # can infer it here if it's not set.
set(IDF_PATH ${CMAKE_CURRENT_LIST_DIR}) set(IDF_PATH ${CMAKE_CURRENT_LIST_DIR})
set($ENV{IDF_PATH} "${IDF_PATH}") set($ENV{IDF_PATH} "${IDF_PATH}")
endif() endif()
# #
# Load cmake modules # Load cmake modules
# #
set(CMAKE_MODULE_PATH "${IDF_PATH}/tools/cmake" "${IDF_PATH}/tools/cmake/third_party" ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH
"${IDF_PATH}/tools/cmake"
"${IDF_PATH}/tools/cmake/third_party"
${CMAKE_MODULE_PATH})
include(GetGitRevisionDescription) include(GetGitRevisionDescription)
include(utilities) include(utilities)
include(components) include(components)
@ -29,85 +32,88 @@ set_default(PYTHON "python")
# This macro wraps the cmake 'project' command to add # This macro wraps the cmake 'project' command to add
# all of the IDF-specific functionality required # all of the IDF-specific functionality required
# #
# Implementation Note: This macro wraps 'project' on purpose, because cmake has some # Implementation Note: This macro wraps 'project' on purpose, because cmake has
# backwards-compatible magic where if you don't call "project" in the top-level # some backwards-compatible magic where if you don't call "project" in the
# CMakeLists file, it will call it implicitly. However, the implict project will not # top-level CMakeLists file, it will call it implicitly. However, the implicit
# have CMAKE_TOOLCHAIN_FILE set and therefore tries to create a native build project. # 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 # 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... # top-level "project" call but customize it to do what we want in the IDF build.
# #
macro(project name) macro(project name)
# Set global variables used by rest of the build # Set global variables used by rest of the build
idf_set_global_variables() idf_set_global_variables()
# Search COMPONENT_DIRS for COMPONENTS, make a list of full paths to each component in COMPONENT_PATHS # Search COMPONENT_DIRS for COMPONENTS, make a list of full paths to each
components_find_all("${COMPONENT_DIRS}" "${COMPONENTS}" COMPONENT_PATHS COMPONENTS) # component in COMPONENT_PATHS
components_find_all("${COMPONENT_DIRS}" "${COMPONENTS}"
COMPONENT_PATHS COMPONENTS)
# Print list of components # Print list of components
string(REPLACE ";" " " COMPONENTS_SPACES "${COMPONENTS}") string(REPLACE ";" " " COMPONENTS_SPACES "${COMPONENTS}")
message(STATUS "Component names: ${COMPONENTS_SPACES}") message(STATUS "Component names: ${COMPONENTS_SPACES}")
unset(COMPONENTS_SPACES) unset(COMPONENTS_SPACES)
message(STATUS "Component paths: ${COMPONENT_PATHS}") message(STATUS "Component paths: ${COMPONENT_PATHS}")
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 so rest of the build knows the configuration
include(${SDKCONFIG_CMAKE}) include(${SDKCONFIG_CMAKE})
# Now the configuration is loaded, set the toolchain appropriately # Now the configuration is loaded, set the toolchain appropriately
# #
# TODO: support more toolchains than just ESP32 # TODO: support more toolchains than just ESP32
set(CMAKE_TOOLCHAIN_FILE $ENV{IDF_PATH}/tools/cmake/toolchain-esp32.cmake) set(CMAKE_TOOLCHAIN_FILE $ENV{IDF_PATH}/tools/cmake/toolchain-esp32.cmake)
# Declare the actual cmake-level project # Declare the actual cmake-level project
_project(${name} ASM C CXX) _project(${name} ASM C CXX)
# generate compile_commands.json (needs to come after project) # generate compile_commands.json (needs to come after project)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1) set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
# Verify the environment is configured correctly # Verify the environment is configured correctly
idf_verify_environment() idf_verify_environment()
# Add some idf-wide definitions # Add some idf-wide definitions
idf_set_global_compiler_options() idf_set_global_compiler_options()
# Check git revision (may trigger reruns of cmake) # Check git revision (may trigger reruns of cmake)
## sets IDF_VER to IDF git revision ## sets IDF_VER to IDF git revision
idf_get_git_revision() idf_get_git_revision()
## if project uses git, retrieve revision ## if project uses git, retrieve revision
git_describe(PROJECT_VER "${CMAKE_CURRENT_SOURCE_DIR}") git_describe(PROJECT_VER "${CMAKE_CURRENT_SOURCE_DIR}")
# Include any top-level project_include.cmake files from components # Include any top-level project_include.cmake files from components
foreach(component ${COMPONENT_PATHS}) foreach(component ${COMPONENT_PATHS})
include_if_exists("${component}/project_include.cmake") include_if_exists("${component}/project_include.cmake")
endforeach() endforeach()
# #
# Add each component to the build as a library # Add each component to the build as a library
# #
foreach(COMPONENT_PATH ${COMPONENT_PATHS}) foreach(COMPONENT_PATH ${COMPONENT_PATHS})
get_filename_component(COMPONENT_NAME ${COMPONENT_PATH} NAME) get_filename_component(COMPONENT_NAME ${COMPONENT_PATH} NAME)
add_subdirectory(${COMPONENT_PATH} ${COMPONENT_NAME}) add_subdirectory(${COMPONENT_PATH} ${COMPONENT_NAME})
endforeach() endforeach()
unset(COMPONENT_NAME) unset(COMPONENT_NAME)
unset(COMPONENT_PATH) unset(COMPONENT_PATH)
# #
# Add the app executable to the build (has name of PROJECT.elf) # Add the app executable to the build (has name of PROJECT.elf)
# #
idf_add_executable() idf_add_executable()
# Write project description JSON file # Write project description JSON file
configure_file("${IDF_PATH}/tools/cmake/project_description.json.in" configure_file("${IDF_PATH}/tools/cmake/project_description.json.in"
"${CMAKE_BINARY_DIR}/project_description.json") "${CMAKE_BINARY_DIR}/project_description.json")
# #
# Finish component registration (add cross-dependencies, make # Finish component registration (add cross-dependencies, make
# executable dependent on all components) # executable dependent on all components)
# #
components_finish_registration() components_finish_registration()
endmacro(project) endmacro()

32
tools/cmake/run_cmake_lint.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
#
# Run cmakelint on all cmake files in IDF_PATH (except third party)
#
# cmakelint: https://github.com/richq/cmake-lint
#
# NOTE: This script makes use of features in (currently unreleased)
# cmakelint >1.4. Install directly from github as follows:
#
# pip install https://github.com/richq/cmake-lint/archive/058c6c0ed2536.zip
#
if [ -z "${IDF_PATH}" ]; then
echo "IDF_PATH variable needs to be set"
exit 3
fi
# exclusions include some third-party directories which contain upstream
# CMakeLists files
find ${IDF_PATH} \
-name build -prune \
-o -name third_party -prune \
\
-o -name 'nghttp2' -prune \
-o -name 'cJSON' -prune \
-o -name 'Findsodium.cmake' -prune \
\
-o -name CMakeLists.txt -print0 \
-o -name '*.cmake' -print0 \
| xargs -0 cmakelint --linelength=120 --spaces=4

View File

@ -16,17 +16,17 @@
# #
# #
if(NOT DATA_FILE) if(NOT DATA_FILE)
message(FATAL_ERROR "DATA_FILE for converting must be specified") message(FATAL_ERROR "DATA_FILE for converting must be specified")
endif() endif()
if(NOT SOURCE_FILE) if(NOT SOURCE_FILE)
message(FATAL_ERROR "SOURCE_FILE destination must be specified") message(FATAL_ERROR "SOURCE_FILE destination must be specified")
endif() endif()
file(READ "${DATA_FILE}" data HEX) file(READ "${DATA_FILE}" data HEX)
if(FILE_TYPE STREQUAL "TEXT") if(FILE_TYPE STREQUAL "TEXT")
set(data "${data}00") # null-byte terimnation set(data "${data}00") # null-byte terimnation
endif() endif()
## Convert string of raw hex bytes to lines of hex bytes in C array format ## Convert string of raw hex bytes to lines of hex bytes in C array format
@ -41,7 +41,7 @@ string(MAKE_C_IDENTIFIER "${source_filename}" varname)
file(WRITE "${SOURCE_FILE}" "/*\n") file(WRITE "${SOURCE_FILE}" "/*\n")
file(APPEND "${SOURCE_FILE}" " * Data converted from ${DATA_FILE}\n") file(APPEND "${SOURCE_FILE}" " * Data converted from ${DATA_FILE}\n")
if(FILE_TYPE STREQUAL "TEXT") if(FILE_TYPE STREQUAL "TEXT")
file(APPEND "${SOURCE_FILE}" " * (null byte appended)\n") file(APPEND "${SOURCE_FILE}" " * (null byte appended)\n")
endif() endif()
file(APPEND "${SOURCE_FILE}" " */\n") file(APPEND "${SOURCE_FILE}" " */\n")
file(APPEND "${SOURCE_FILE}" "#include <stdlib.h>\n") file(APPEND "${SOURCE_FILE}" "#include <stdlib.h>\n")

View File

@ -1,7 +1,7 @@
set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER xtensa-esp32-elf-gcc) set(CMAKE_C_COMPILER xtensa-esp32-elf-gcc)
set(CMAKE_CXX_COMPILER xtensa-esp32-elf-g++) set(CMAKE_CXX_COMPILER xtensa-esp32-elf-g++)
set(CMAKE_ASM_COMPILER xtensa-esp32-elf-gcc) set(CMAKE_ASM_COMPILER xtensa-esp32-elf-gcc)
set(CMAKE_EXE_LINKER_FLAGS "-nostdlib" CACHE STRING "Linker Base Flags") set(CMAKE_EXE_LINKER_FLAGS "-nostdlib" CACHE STRING "Linker Base Flags")

View File

@ -8,13 +8,13 @@
# - Default value as provided to function # - Default value as provided to function
# #
function(set_default variable default_value) function(set_default variable default_value)
if(NOT ${variable}) if(NOT ${variable})
if($ENV{${variable}}) if($ENV{${variable}})
set(${variable} $ENV{${variable}} PARENT_SCOPE) set(${variable} $ENV{${variable}} PARENT_SCOPE)
else() else()
set(${variable} ${default_value} PARENT_SCOPE) set(${variable} ${default_value} PARENT_SCOPE)
endif()
endif() endif()
endif()
endfunction() endfunction()
# spaces2list # spaces2list
@ -27,8 +27,8 @@ endfunction()
# #
# TODO: look at cmake separate_arguments, which is quote-aware # TODO: look at cmake separate_arguments, which is quote-aware
function(spaces2list variable_name) function(spaces2list variable_name)
string(REPLACE " " ";" tmp "${${variable_name}}") string(REPLACE " " ";" tmp "${${variable_name}}")
set("${variable_name}" "${tmp}" PARENT_SCOPE) set("${variable_name}" "${tmp}" PARENT_SCOPE)
endfunction() endfunction()
@ -38,9 +38,9 @@ endfunction()
# to a cmake list (semicolon-delimited), one line per item # to a cmake list (semicolon-delimited), one line per item
# #
function(lines2list variable_name) function(lines2list variable_name)
string(REGEX REPLACE "\r?\n" ";" tmp "${${variable_name}}") string(REGEX REPLACE "\r?\n" ";" tmp "${${variable_name}}")
string(REGEX REPLACE ";;" ";" tmp "${tmp}") string(REGEX REPLACE ";;" ";" tmp "${tmp}")
set("${variable_name}" "${tmp}" PARENT_SCOPE) set("${variable_name}" "${tmp}" PARENT_SCOPE)
endfunction() endfunction()
@ -54,23 +54,23 @@ endfunction()
# Avoids timestamp updates for re-generated files where content hasn't # Avoids timestamp updates for re-generated files where content hasn't
# changed. # changed.
function(move_if_different source destination) function(move_if_different source destination)
set(do_copy 1) set(do_copy 1)
file(GLOB dest_exists ${destination}) file(GLOB dest_exists ${destination})
if(dest_exists) if(dest_exists)
file(MD5 ${source} source_md5) file(MD5 ${source} source_md5)
file(MD5 ${destination} dest_md5) file(MD5 ${destination} dest_md5)
if(source_md5 STREQUAL dest_md5) if(source_md5 STREQUAL dest_md5)
set(do_copy "") set(do_copy "")
endif()
endif() endif()
endif()
if(do_copy) if(do_copy)
message("Moving ${source} -> ${destination}") message("Moving ${source} -> ${destination}")
file(RENAME ${source} ${destination}) file(RENAME ${source} ${destination})
else() else()
message("Not moving ${source} -> ${destination}") message("Not moving ${source} -> ${destination}")
file(REMOVE ${source}) file(REMOVE ${source})
endif() endif()
endfunction() endfunction()
@ -80,10 +80,10 @@ endfunction()
# This adds global options, set target properties for # This adds global options, set target properties for
# component-specific flags # component-specific flags
function(add_cxx_compile_options) function(add_cxx_compile_options)
foreach(option ${ARGV}) foreach(option ${ARGV})
# note: the Visual Studio Generator doesn't support this... # note: the Visual Studio Generator doesn't support this...
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${option}>) add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${option}>)
endforeach() endforeach()
endfunction() endfunction()
# add_compile_options variant for C code only # add_compile_options variant for C code only
@ -91,10 +91,10 @@ endfunction()
# This adds global options, set target properties for # This adds global options, set target properties for
# component-specific flags # component-specific flags
function(add_c_compile_options) function(add_c_compile_options)
foreach(option ${ARGV}) foreach(option ${ARGV})
# note: the Visual Studio Generator doesn't support this... # note: the Visual Studio Generator doesn't support this...
add_compile_options($<$<COMPILE_LANGUAGE:C>:${option}>) add_compile_options($<$<COMPILE_LANGUAGE:C>:${option}>)
endforeach() endforeach()
endfunction() endfunction()
@ -103,46 +103,45 @@ endfunction()
# to a binary object as part of the build # to a binary object as part of the build
function(target_add_binary_data target embed_file embed_type) function(target_add_binary_data target embed_file embed_type)
get_filename_component(embed_file "${embed_file}" ABSOLUTE) get_filename_component(embed_file "${embed_file}" ABSOLUTE)
get_filename_component(name "${embed_file}" NAME) get_filename_component(name "${embed_file}" NAME)
set(embed_srcfile "${CMAKE_BINARY_DIR}/${name}.c") set(embed_srcfile "${CMAKE_BINARY_DIR}/${name}.c")
add_custom_command(OUTPUT "${embed_srcfile}" add_custom_command(OUTPUT "${embed_srcfile}"
COMMAND "${CMAKE_COMMAND}" COMMAND "${CMAKE_COMMAND}"
-D "DATA_FILE=${embed_file}" -D "DATA_FILE=${embed_file}"
-D "SOURCE_FILE=${embed_srcfile}" -D "SOURCE_FILE=${embed_srcfile}"
-D "FILE_TYPE=${embed_type}" -D "FILE_TYPE=${embed_type}"
-P "${IDF_PATH}/tools/cmake/scripts/data_file_to_c.cmake" -P "${IDF_PATH}/tools/cmake/scripts/data_file_to_c.cmake"
MAIN_DEPENDENCY "${embed_file}" MAIN_DEPENDENCY "${embed_file}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${embed_srcfile}") set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${embed_srcfile}")
target_sources("${target}" PRIVATE "${embed_srcfile}") target_sources("${target}" PRIVATE "${embed_srcfile}")
endfunction() endfunction()
macro(include_if_exists path) macro(include_if_exists path)
if(EXISTS "${path}") if(EXISTS "${path}")
include("${path}") include("${path}")
endif() endif()
endmacro(include_if_exists) endmacro()
# Append a single line to the file specified # Append a single line to the file specified
# The line ending is determined by the host OS # The line ending is determined by the host OS
function(file_append_line file line) function(file_append_line file line)
if(ENV{MSYSTEM} OR CMAKE_HOST_WIN32) if(ENV{MSYSTEM} OR CMAKE_HOST_WIN32)
set(line_ending "\r\n") set(line_ending "\r\n")
else() # unix else() # unix
set(line_ending "\n") set(line_ending "\n")
endif() endif()
file(READ ${file} existing) file(READ ${file} existing)
string(FIND ${existing} ${line_ending} last_newline REVERSE) string(FIND ${existing} ${line_ending} last_newline REVERSE)
string(LENGTH ${existing} length) string(LENGTH ${existing} length)
math(EXPR length "${length}-1") math(EXPR length "${length}-1")
if(NOT length EQUAL last_newline) # file doesn't end with a newline if(NOT length EQUAL last_newline) # file doesn't end with a newline
file(APPEND "${file}" "${line_ending}") file(APPEND "${file}" "${line_ending}")
endif() endif()
file(APPEND "${file}" "${line}${line_ending}") file(APPEND "${file}" "${line}${line_ending}")
endfunction() endfunction()