diff --git a/src/cmake/on_device.cmake b/src/cmake/on_device.cmake index 00a5fffc..b4c53b96 100644 --- a/src/cmake/on_device.cmake +++ b/src/cmake/on_device.cmake @@ -15,16 +15,22 @@ function(pico_get_runtime_output_directory TARGET output_path_name) set(${output_path_name} ${output_path} PARENT_SCOPE) endfunction() +# pico_add_hex_output(TARGET) +# \brief\ Generate a hex file for the target function(pico_add_hex_output TARGET) pico_get_runtime_output_directory(${TARGET} output_path) add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_OBJCOPY} -Oihex $ ${output_path}$>,$,$>.hex VERBATIM) endfunction() +# pico_add_bin_output(TARGET) +# \brief\ Generate a bin file for the target function(pico_add_bin_output TARGET) pico_get_runtime_output_directory(${TARGET} output_path) add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_OBJCOPY} -Obinary $ ${output_path}$>,$,$>.bin VERBATIM) endfunction() +# pico_add_dis_output(TARGET) +# \brief\ Generate a disassembly file for the target function(pico_add_dis_output TARGET) pico_get_runtime_output_directory(${TARGET} output_path) @@ -45,6 +51,10 @@ function(pico_add_dis_output TARGET) ) endfunction() +# pico_add_extra_outputs(TARGET) +# \brief_nodesc\ Perform post-build actions for the target +# +# Perform picotool processing and add disassembly, hex, bin, map, and uf2 outputs for the target function(pico_add_extra_outputs TARGET) # Disassembly will be nonsense for encrypted binaries, # so disassemble before picotool processing diff --git a/src/common/pico_binary_info/CMakeLists.txt b/src/common/pico_binary_info/CMakeLists.txt index d2bfd691..5da8fb5a 100644 --- a/src/common/pico_binary_info/CMakeLists.txt +++ b/src/common/pico_binary_info/CMakeLists.txt @@ -9,11 +9,19 @@ endif() target_link_libraries(pico_binary_info INTERFACE pico_binary_info_headers) +# pico_set_program_name(TARGET name) +# \brief\ Set the program name for the target +# +# \param\ name The program name to set function(pico_set_program_name TARGET name) # PICO_BUILD_DEFINE: PICO_PROGRAM_NAME, value passed to pico_set_program_name, type=string, group=pico_binary_info target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_NAME="${name}") endfunction() +# pico_set_program_description(TARGET description) +# \brief\ Set the program description for the target +# +# \param\ description The program description to set function(pico_set_program_description TARGET description) # since this is the command line, we will remove newlines string(REPLACE "\n" " " description ${description}) @@ -22,11 +30,19 @@ function(pico_set_program_description TARGET description) target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_DESCRIPTION="${description}") endfunction() +# pico_set_program_url(TARGET url) +# \brief\ Set the program URL for the target +# +# \param\ url The program URL to set function(pico_set_program_url TARGET url) # PICO_BUILD_DEFINE: PICO_PROGRAM_URL, value passed to pico_set_program_url, type=string, group=pico_binary_info target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_URL="${url}") endfunction() +# pico_set_program_version(TARGET version) +# \brief\ Set the program version for the target +# +# \param\ version The program version to set function(pico_set_program_version TARGET version) # PICO_BUILD_DEFINE: PICO_PROGRAM_VERSION_STRING, value passed to pico_set_program_version, type=string, group=pico_binary_info target_compile_definitions(${TARGET} PRIVATE -DPICO_PROGRAM_VERSION_STRING="${version}") diff --git a/src/rp2040/boot_stage2/CMakeLists.txt b/src/rp2040/boot_stage2/CMakeLists.txt index ba42256b..2798b364 100644 --- a/src/rp2040/boot_stage2/CMakeLists.txt +++ b/src/rp2040/boot_stage2/CMakeLists.txt @@ -33,7 +33,13 @@ set(PICO_BOOT_STAGE2_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "") pico_add_library(boot_stage2_headers) target_include_directories(boot_stage2_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) -# by convention the first source file name without extension is used for the binary info name +# pico_define_boot_stage2(NAME SOURCES) +# \brief\ Define a boot stage 2 target. +# +# By convention the first source file name without extension is used for the binary info name +# +# \param\ NAME The name of the boot stage 2 target +# \param\ SOURCES The source files to link into the boot stage 2 function(pico_define_boot_stage2 NAME SOURCES) add_executable(${NAME} ${SOURCES} @@ -97,7 +103,12 @@ endmacro() pico_define_boot_stage2(bs2_default ${PICO_DEFAULT_BOOT_STAGE2_FILE}) +# pico_clone_default_boot_stage2(NAME) +# \brief_nodesc\ Clone the default boot stage 2 target. +# # Create a new boot stage 2 target using the default implementation for the current build (PICO_BOARD derived) +# +# \param\ NAME The name of the new boot stage 2 target function(pico_clone_default_boot_stage2 NAME) pico_define_boot_stage2(${NAME} ${PICO_DEFAULT_BOOT_STAGE2_FILE}) endfunction() diff --git a/src/rp2350/boot_stage2/CMakeLists.txt b/src/rp2350/boot_stage2/CMakeLists.txt index e878ccc5..fbf95b53 100644 --- a/src/rp2350/boot_stage2/CMakeLists.txt +++ b/src/rp2350/boot_stage2/CMakeLists.txt @@ -33,7 +33,13 @@ set(PICO_BOOT_STAGE2_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "") pico_add_library(boot_stage2_headers) target_include_directories(boot_stage2_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) -# by convention the first source file name without extension is used for the binary info name +# pico_define_boot_stage2(NAME SOURCES) +# \brief\ Define a boot stage 2 target. +# +# By convention the first source file name without extension is used for the binary info name +# +# \param\ NAME The name of the boot stage 2 target +# \param\ SOURCES The source files to link into the boot stage 2 function(pico_define_boot_stage2 NAME SOURCES) add_executable(${NAME} ${SOURCES} @@ -97,7 +103,12 @@ endmacro() pico_define_boot_stage2(bs2_default ${PICO_DEFAULT_BOOT_STAGE2_FILE}) +# pico_clone_default_boot_stage2(NAME) +# \brief_nodesc\ Clone the default boot stage 2 target. +# # Create a new boot stage 2 target using the default implementation for the current build (PICO_BOARD derived) +# +# \param\ NAME The name of the new boot stage 2 target function(pico_clone_default_boot_stage2 NAME) pico_define_boot_stage2(${NAME} ${PICO_DEFAULT_BOOT_STAGE2_FILE}) endfunction() diff --git a/src/rp2_common/pico_btstack/CMakeLists.txt b/src/rp2_common/pico_btstack/CMakeLists.txt index a3681603..593b666f 100644 --- a/src/rp2_common/pico_btstack/CMakeLists.txt +++ b/src/rp2_common/pico_btstack/CMakeLists.txt @@ -302,9 +302,15 @@ if (EXISTS ${PICO_BTSTACK_PATH}/${BTSTACK_TEST_PATH}) pico_promote_common_scope_vars() - # Make a GATT header file from a BTstack GATT file - # Pass the target library name library type and path to the GATT input file - # To add additional directories to the gatt #import path, add them to the end of the argument list. + # pico_btstack_make_gatt_header(TARGET_LIB TARGET_TYPE GATT_FILE) + # \brief\ Make a GATT header file from a BTstack GATT file. + # + # Pass the target library name, library type, and path to the GATT input file. + # To add additional directories to the gatt import path, add them to the end of the argument list. + # + # \param\ TARGET_LIB The target library name + # \param\ TARGET_TYPE The target library type + # \param\ GATT_FILE The path to the GATT input file function(pico_btstack_make_gatt_header TARGET_LIB TARGET_TYPE GATT_FILE) find_package (Python3 REQUIRED COMPONENTS Interpreter) get_filename_component(GATT_NAME "${GATT_FILE}" NAME_WE) diff --git a/src/rp2_common/pico_cyw43_driver/CMakeLists.txt b/src/rp2_common/pico_cyw43_driver/CMakeLists.txt index 6fd1998b..a7570a29 100644 --- a/src/rp2_common/pico_cyw43_driver/CMakeLists.txt +++ b/src/rp2_common/pico_cyw43_driver/CMakeLists.txt @@ -131,16 +131,22 @@ if (EXISTS ${PICO_CYW43_DRIVER_PATH}/${CYW43_DRIVER_TEST_FILE}) ) endif() - # Set an ip address in a compile definition - # target name, target type, compile definition name to set then address in a string - # This can be used to set the following compile definitions - # CYW43_DEFAULT_IP_STA_ADDRESS - # CYW43_DEFAULT_IP_STA_GATEWAY - # CYW43_DEFAULT_IP_AP_ADDRESS - # CYW43_DEFAULT_IP_AP_GATEWAY - # CYW43_DEFAULT_IP_MASK - # CYW43_DEFAULT_IP_DNS + # pico_configure_ip4_address(TARGET_LIB TARGET_TYPE DEF_NAME IP_ADDRESS_STR) + # \brief\ Set an ip address in a compile definition + # + # This can be used to set the following compile definitions; + # CYW43_DEFAULT_IP_STA_ADDRESS; + # CYW43_DEFAULT_IP_STA_GATEWAY; + # CYW43_DEFAULT_IP_AP_ADDRESS; + # CYW43_DEFAULT_IP_AP_GATEWAY; + # CYW43_DEFAULT_IP_MASK; + # CYW43_DEFAULT_IP_DNS; # e.g. pico_configure_ip4_address(picow_tcpip_server_background PRIVATE CYW43_DEFAULT_IP_STA_ADDRESS "10.3.15.204") + # + # \param\ TARGET_LIB The target library to set the ip address for + # \param\ TARGET_TYPE The type of target library + # \param\ DEF_NAME The name of the compile definition to set + # \param\ IP_ADDRESS_STR The ip address to set function(pico_configure_ip4_address TARGET_LIB TARGET_TYPE DEF_NAME IP_ADDRESS_STR) string(REGEX MATCHALL "[0-9]+" IP_ADDRESS_LIST ${IP_ADDRESS_STR}) list(LENGTH IP_ADDRESS_LIST IP_ADDRESS_COMPONENT_COUNT) diff --git a/src/rp2_common/pico_lwip/tools/CMakeLists.txt b/src/rp2_common/pico_lwip/tools/CMakeLists.txt index 1539ac00..796075f3 100644 --- a/src/rp2_common/pico_lwip/tools/CMakeLists.txt +++ b/src/rp2_common/pico_lwip/tools/CMakeLists.txt @@ -1,5 +1,13 @@ -# Compile the http content into a source file "pico_fsdata.inc" in a format suitable for the lwip httpd server -# Pass the target library name library type and the list of httpd content +# pico_set_lwip_httpd_content(TARGET_LIB TARGET_TYPE HTTPD_FILES...) +# \ingroup\ pico_lwip +# \brief_nodesc\ Compile the http content into a source file for lwip. +# +# Compile the http content into a source file "pico_fsdata.inc" in a format suitable for the lwip httpd server. +# Pass the target library name, library type, and the list of httpd content files to compile. +# +# \param\ TARGET_LIB The target library name +# \param\ TARGET_TYPE The type of the target library +# \param\ HTTPD_FILES The list of httpd content files to compile function(pico_set_lwip_httpd_content TARGET_LIB TARGET_TYPE) find_package (Python3 REQUIRED COMPONENTS Interpreter) set(HTTPD_CONTENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") diff --git a/src/rp2_common/pico_runtime/CMakeLists.txt b/src/rp2_common/pico_runtime/CMakeLists.txt index da329e69..59c82520 100644 --- a/src/rp2_common/pico_runtime/CMakeLists.txt +++ b/src/rp2_common/pico_runtime/CMakeLists.txt @@ -51,22 +51,26 @@ elseif (PICO_C_COMPILER_IS_CLANG) # target_link_options(pico_runtime INTERFACE "-nostdlib") endif() -# pico_minimize_runtime((INCLUDE ...) (EXCLUDE ...)) +# pico_minimize_runtime(TARGET [INCLUDE ...] [EXCLUDE ...]) +# \brief\ Minimize the runtime components for the target # # INCLUDE/EXCLUDE can contain any of the following (all defaulting to not included) # -# DEFAULT_ALARM_POOL - default alarm pool setup -# PRINTF - full printf support -# PRINTF_MINIMAL - printf support without the following -# PRINTF_FLOAT - to control float support if printf is enabled -# PRINTF_EXPONENTIAL -# PRINTF_LONG_LONG -# PRINTF_PTRDIFF_T -# FLOAT - support for single-precision floating point -# DOUBLE - support for double-precision floating point -# FPGA_CHECK - checks for FPGA which allows Raspberry Pi to run your binary on FPGA -# PANIC - default panic impl which brings in stdio -# AUTO_INIT_MUTEX - auto init mutexes; without this you get no printf mutex either - +# DEFAULT_ALARM_POOL - default alarm pool setup; +# PRINTF - full printf support; +# PRINTF_MINIMAL - printf support without the following; +# PRINTF_FLOAT - to control float support if printf is enabled; +# PRINTF_EXPONENTIAL - to control exponential support if printf is enabled; +# PRINTF_LONG_LONG - to control long long support if printf is enabled; +# PRINTF_PTRDIFF_T - to control ptrdiff_t support if printf is enabled; +# FLOAT - support for single-precision floating point; +# DOUBLE - support for double-precision floating point; +# FPGA_CHECK - checks for FPGA which allows Raspberry Pi to run your binary on FPGA; +# PANIC - default panic impl which brings in stdio; +# AUTO_INIT_MUTEX - auto init mutexes, without this you get no printf mutex either; +# +# \param\ INCLUDE The items to include +# \param\ EXCLUDE The items to exclude function(pico_minimize_runtime TARGET) set(ALL_ITEMS DEFAULT_ALARM_POOL diff --git a/src/rp2_common/pico_standard_link/CMakeLists.txt b/src/rp2_common/pico_standard_link/CMakeLists.txt index 53eaa84f..484abc89 100644 --- a/src/rp2_common/pico_standard_link/CMakeLists.txt +++ b/src/rp2_common/pico_standard_link/CMakeLists.txt @@ -5,6 +5,10 @@ if (NOT TARGET pico_standard_link) target_link_libraries(pico_standard_link INTERFACE boot_stage2_headers) endif() + # pico_add_link_depend(TARGET dependency) + # \brief\ Add a link time dependency to the target + # + # \param\ dependency The dependency to add function(pico_add_link_depend TARGET dependency) get_target_property(target_type ${TARGET} TYPE) if (${target_type} STREQUAL "INTERFACE_LIBRARY") @@ -21,11 +25,18 @@ if (NOT TARGET pico_standard_link) set_target_properties(${TARGET} PROPERTIES ${PROP} "${_LINK_DEPENDS}") endfunction() - # need this because cmake does not appear to have a way to override an INTERFACE variable + # pico_set_linker_script(TARGET LDSCRIPT) + # \brief\ Set the linker script for the target + # + # \param\ LDSCRIPT Full path to the linker script to set function(pico_set_linker_script TARGET LDSCRIPT) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_LINKER_SCRIPT ${LDSCRIPT}) endfunction() + # pico_set_binary_type(TARGET TYPE) + # \brief\ Set the binary type for the target + # + # \param\ TYPE The binary type to set function(pico_set_binary_type TARGET TYPE) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_BINARY_TYPE ${TYPE}) endfunction() diff --git a/src/rp2_common/pico_stdio/CMakeLists.txt b/src/rp2_common/pico_stdio/CMakeLists.txt index 5798b8d2..195a5b36 100644 --- a/src/rp2_common/pico_stdio/CMakeLists.txt +++ b/src/rp2_common/pico_stdio/CMakeLists.txt @@ -26,18 +26,34 @@ if (NOT TARGET pico_stdio) pico_mirrored_target_link_libraries(pico_stdio INTERFACE pico_printf) endif() + # pico_enable_stdio_uart(TARGET ENABLED) + # \brief\ Enable stdio UART for the target + # + # \param\ ENABLED Whether to enable stdio UART function(pico_enable_stdio_uart TARGET ENABLED) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_STDIO_UART ${ENABLED}) endfunction() + # pico_enable_stdio_usb(TARGET ENABLED) + # \brief\ Enable stdio USB for the target + # + # \param\ ENABLED Whether to enable stdio USB function(pico_enable_stdio_usb TARGET ENABLED) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_STDIO_USB ${ENABLED}) endfunction() + # pico_enable_stdio_semihosting(TARGET ENABLED) + # \brief\ Enable stdio semi-hosting for the target + # + # \param\ ENABLED Whether to enable stdio semi-hosting function(pico_enable_stdio_semihosting TARGET ENABLED) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_STDIO_SEMIHOSTING ${ENABLED}) endfunction() + # pico_enable_stdio_rtt(TARGET ENABLED) + # \brief\ Enable stdio RTT for the target + # + # \param\ ENABLED Whether to enable stdio RTT function(pico_enable_stdio_rtt TARGET ENABLED) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_STDIO_RTT ${ENABLED}) endfunction() diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 7d68c910..5273840a 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -175,13 +175,19 @@ function(picotool_check_default_keys TARGET) picotool_compare_keys(${TARGET} ${picotool_enc_sigfile} private.pem "encrypted signing") endfunction() -# Generate pio header and include it in the build -# PICO_CMAKE_CONFIG: PICO_DEFAULT_PIOASM_OUTPUT_FORMAT, Default output format used by pioasm when using pico_generate_pio_header, type=string, default=c-sdk, group=build +# pico_generate_pio_header(TARGET PIO_FILES... [OUTPUT_FORMAT ] [OUTPUT_DIR ]) +# \ingroup\ pico_pio +# \brief\ Generate pio header and include it in the build +# +# \param\ PIO_FILES The PIO files to generate the header for +# \param\ OUTPUT_FORMAT The output format to use for the pio header +# \param\ OUTPUT_DIR The directory to output the pio header to function(pico_generate_pio_header TARGET) pico_init_pioasm() # Note that PATH is not a valid argument but was previously ignored (and happens to be passed by pico-extras) cmake_parse_arguments(pico_generate_pio_header "" "OUTPUT_FORMAT;OUTPUT_DIR;PATH" "" ${ARGN} ) + # PICO_CMAKE_CONFIG: PICO_DEFAULT_PIOASM_OUTPUT_FORMAT, Default output format used by pioasm when using pico_generate_pio_header, type=string, default=c-sdk, group=build if (pico_generate_pio_header_OUTPUT_FORMAT) set(OUTPUT_FORMAT "${pico_generate_pio_header_OUTPUT_FORMAT}") elseif(DEFINED PICO_DEFAULT_PIOASM_OUTPUT_FORMAT) @@ -230,10 +236,13 @@ function(pico_generate_pio_header TARGET) endfunction() # pico_package_uf2_output(TARGET PACKADDR) -# Package a UF2 output to be written to the PACKADDR address. This can be -# used with a no_flash binary to write the UF2 to flash when dragging & +# \brief\ Package a UF2 output to be written to the PACKADDR address. +# This can be used with a no_flash binary to write the UF2 to flash when dragging & # dropping, and it will be copied to SRAM by the bootrom before execution. -# This sets PICOTOOL_UF2_PACKAGE_ADDR to PACKADDR. +# +# This sets the target property PICOTOOL_UF2_PACKAGE_ADDR to PACKADDR. +# +# \param\ PACKADDR The address to package the UF2 to function(pico_package_uf2_output TARGET PACKADDR) picotool_check_configurable(${TARGET}) set_target_properties(${TARGET} PROPERTIES @@ -242,8 +251,11 @@ function(pico_package_uf2_output TARGET PACKADDR) endfunction() # pico_set_otp_key_output_file(TARGET OTPFILE) -# Output the public key hash and other necessary rows to an otp JSON file. -# This sets PICOTOOL_OTP_FILE to OTPFILE. +# \brief\ Output the public key hash and other necessary rows to an otp JSON file. +# +# This sets the target property PICOTOOL_OTP_FILE to OTPFILE. +# +# \param\ OTPFILE The OTP file to output the public key hash and other necessary rows to function(pico_set_otp_key_output_file TARGET OTPFILE) picotool_check_configurable(${TARGET}) set_target_properties(${TARGET} PROPERTIES @@ -252,9 +264,12 @@ function(pico_set_otp_key_output_file TARGET OTPFILE) endfunction() # pico_load_map_clear_sram(TARGET) +# \brief_nodesc\ Adds a load map entry to clear all of SRAM +# # Adds an entry to the load map to instruct the bootrom to clear all of SRAM -# before loading the binary. This appends the `--clear` argument -# to PICOTOOL_EXTRA_PROCESS_ARGS. +# before loading the binary. +# +# This appends the `--clear` argument to the target property PICOTOOL_EXTRA_PROCESS_ARGS. function(pico_load_map_clear_sram TARGET) picotool_check_configurable(${TARGET}) # get and set, to inherit list @@ -268,11 +283,20 @@ function(pico_load_map_clear_sram TARGET) ) endfunction() -# pico_set_binary_version( [MAJOR ] [MINOR ] [ROLLBACK ] [ROLLBACK_ROWS ]) +# pico_set_binary_version(TARGET [MAJOR ] [MINOR ] [ROLLBACK ] [ROWS ]) +# \brief_nodesc\ Add a version item to the metadata block +# # Adds a version item to the metadata block, with the given major, minor and -# rollback version, along with the rollback rows. These are appended as arguments -# to PICOTOOL_EXTRA_PROCESS_ARGS if setting the rollback version, or set as compile -# definitions if only setting the major/minor versions. +# rollback version, along with the rollback rows. +# +# These are appended as arguments to the target property PICOTOOL_EXTRA_PROCESS_ARGS if setting the +# rollback version, or set as compile definitions if only setting the major/minor +# versions. +# +# \param\ MAJOR The major version to set +# \param\ MINOR The minor version to set +# \param\ ROLLBACK The rollback version to set +# \param\ ROWS The OTP rows to use for the rollback version function(pico_set_binary_version TARGET) picotool_check_configurable(${TARGET}) set(oneValueArgs MAJOR MINOR ROLLBACK) @@ -321,8 +345,11 @@ function(pico_set_binary_version TARGET) endfunction() # pico_set_uf2_family(TARGET FAMILY) -# Set the UF2 family to use when creating the UF2. -# This sets PICOTOOL_UF2_FAMILY to FAMILY. +# \brief\ Set the UF2 family to use when creating the UF2. +# +# This sets the target property PICOTOOL_UF2_FAMILY to FAMILY. +# +# \param\ FAMILY The UF2 family to use function(pico_set_uf2_family TARGET FAMILY) picotool_check_configurable(${TARGET}) set_target_properties(${TARGET} PROPERTIES @@ -331,11 +358,16 @@ function(pico_set_uf2_family TARGET FAMILY) endfunction() # pico_sign_binary(TARGET [SIGFILE]) -# Sign the target binary with the given PEM signature. This sets -# PICOTOOL_SIGN_OUTPUT to true, PICOTOOL_SIGFILE to SIGFILE (if specified), -# and PICOTOOL_OTP_FILE to ${TARGET}.otp.json (if not already set). To -# specify a common SIGFILE for multiple targets, the SIGFILE property can be +# \brief\ Sign the target binary with the given PEM signature. +# +# This sets the target properties PICOTOOL_SIGN_OUTPUT to true, +# PICOTOOL_SIGFILE to SIGFILE (if specified), and PICOTOOL_OTP_FILE to +# ${TARGET}.otp.json (if not already set). +# +# To specify a common SIGFILE for multiple targets, the SIGFILE property can be # set for a given scope, and then the SIGFILE argument is optional. +# +# \param\ SIGFILE The PEM signature file to use function(pico_sign_binary TARGET) picotool_check_configurable(${TARGET}) # Enforce signing through target properties @@ -361,7 +393,9 @@ function(pico_sign_binary TARGET) endfunction() # pico_hash_binary(TARGET) -# Hash the target binary. This sets PICOTOOL_HASH_OUTPUT to true. +# \brief\ Hash the target binary. +# +# This sets the target property PICOTOOL_HASH_OUTPUT to true. function(pico_hash_binary TARGET) picotool_check_configurable(${TARGET}) # Enforce hashing through target properties @@ -371,8 +405,14 @@ function(pico_hash_binary TARGET) endfunction() # pico_embed_pt_in_binary(TARGET PTFILE) +# \brief_nodesc\ Embed a partition table in the binary +# # Create the specified partition table from JSON, and embed it in the -# block loop. This sets PICOTOOL_EMBED_PT to PTFILE. +# block loop. +# +# This sets the target property PICOTOOL_EMBED_PT to PTFILE. +# +# \param\ PTFILE The partition table JSON file to use function(pico_embed_pt_in_binary TARGET PTFILE) picotool_check_configurable(${TARGET}) set_target_properties(${TARGET} PROPERTIES @@ -381,10 +421,16 @@ function(pico_embed_pt_in_binary TARGET PTFILE) endfunction() # pico_encrypt_binary(TARGET AESFILE [SIGFILE]) +# \brief_nodesc\ Encrypt the taget binary +# # Encrypt the target binary with the given AES key (should be a binary # file containing 32 bytes of a random key), and sign the encrypted binary. -# This sets PICOTOOL_AESFILE to AESFILE, and PICOTOOL_ENC_SIGFILE to SIGFILE -# if present, else PICOTOOL_SIGFILE. +# +# This sets the target properties PICOTOOL_AESFILE to AESFILE, +# and PICOTOOL_ENC_SIGFILE to SIGFILE if present, else PICOTOOL_SIGFILE. +# +# \param\ AESFILE The AES key file to use +# \param\ SIGFILE The PEM signature file to use function(pico_encrypt_binary TARGET AESFILE) picotool_check_configurable(${TARGET}) set_target_properties(${TARGET} PROPERTIES @@ -410,6 +456,8 @@ function(pico_encrypt_binary TARGET AESFILE) endfunction() # pico_add_uf2_output(TARGET) +# \brief_nodesc\ Add a UF2 output using picotool +# # Add a UF2 output using picotool - must be called after # all required properties have been set function(pico_add_uf2_output TARGET) diff --git a/tools/extract_cmake_functions.py b/tools/extract_cmake_functions.py new file mode 100755 index 00000000..bc0b03ed --- /dev/null +++ b/tools/extract_cmake_functions.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2025 Raspberry Pi (Trading) Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# +# Script to scan the Raspberry Pi Pico SDK tree searching for CMake functions +# Outputs a tab separated file of the functions: +# name group signature brief description params +# +# Usage: +# +# tools/extract_cmake_functions.py [output file] +# +# If not specified, output file will be `pico_cmake_functions.tsv` + + +import os +import sys +import re +import csv +import logging + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +scandir = sys.argv[1] +outfile = sys.argv[2] if len(sys.argv) > 2 else 'pico_cmake_functions.tsv' + +CMAKE_FUNCTION_RE = re.compile(r'^\s*#(.*)((\n\s*#.*)*)\n\s*function\(([^\s]*)', re.MULTILINE) + +CMAKE_PICO_FUNCTIONS_RE = re.compile(r'^\s*function\((pico_[^\s\)]*)', re.MULTILINE) + +# Files containing internal functions that don't need to be documented publicly +skip_files = set([ + "pico_sdk_init.cmake", + "pico_utils.cmake", + "no_hardware.cmake", + "find_compiler.cmake", +]) + +skip_groups = set([ + "src", # skip the root src/CMakeLists.txt +]) + +# Other internal functions that don't need to be documented publicly +allowed_missing_functions = set([ + "pico_init_pioasm", + "pico_init_picotool", + "pico_add_platform_library", + "pico_get_runtime_output_directory", + "pico_set_printf_implementation", + "pico_expand_pico_platform", +]) + +# Group descriptions +group_names_descriptions = { + 'boot_stage2': ('Boot Stage 2', 'CMake functions to create stage 2 bootloaders'), + 'pico_binary_info': ('Pico Binary Info', 'CMake functions to add binary info to the output binary'), + 'pico_btstack': ('Pico BTstack', 'CMake functions to configure the bluetooth stack'), + 'pico_lwip': ('Pico LwIP', 'CMake functions to configure LwIP'), + 'pico_cyw43_driver': ('Pico CYW43 Driver', 'CMake functions to configure the CYW43 driver'), + 'pico_runtime': ('Pico Runtime', 'CMake functions to configure the runtime environment'), + 'pico_standard_link': ('Pico Standard Link', 'CMake functions to configure the linker'), + 'pico_stdio': ('Pico Standard I/O', 'CMake functions to configure the standard I/O library'), + 'pico_pio': ('Pico PIO', 'CMake functions to generate PIO headers'), + 'other': ('Other', 'Other CMake functions'), +} + + +all_functions = {} + +for group, (brief, description) in group_names_descriptions.items(): + all_functions['_desc_{group}'.format(group=group)] = { + 'name': '_desc_{group}'.format(group=group), + 'group': group, + 'signature': '', + 'brief': brief, + 'description': description, + 'params': '', + } + +# Supported commands: +# \brief\ +# \brief_nodesc\ +# \param\ +# \ingroup\ +# +# Commands in the middle of a line are not supported +# +# The ; character at the end of a line denotes a hard line break in the description +# The \ character (outside of a command) and the # character are not supported in descriptions +def process_commands(description, name, group, signature): + brief = '' + params = [] + desc = '' + for line in description.split('\n'): + line = line.strip() + if line.startswith('\\'): + _, command, remainder = line.split('\\', 2) + remainder = remainder.strip() + if command == 'param': + # Parameter name and description + params.append(remainder) + elif command == 'brief': + # Brief description + brief = remainder + desc += brief + '\\n' + elif command == 'brief_nodesc': + # Brief description which should not be included in the main description + brief = remainder + elif command == 'ingroup': + # Group name override + group = remainder + else: + logger.error("{}:{} has unknown command: {}".format(group, name, command)) + elif '\\' in line: + logger.error("{}:{} has a line containing '\\': {}".format(group, name, line)) + else: + desc += line + '\\n' + # Check that there are no semicolons in the parameter descriptions, as that's the delimiter for the parameter list + if any([';' in x for x in params]): + logger.error("{}:{} has a parameter description containing ';'".format(group, name)) + # Check that all parameters are in the signature + signature_words = set(re.split('\W+', signature)) + for param in params: + param_name = param.split(' ', maxsplit=1)[0] + if param_name not in signature_words: + logger.error("{}:{} has a parameter {} which is not in the signature {}".format(group, name, param_name, signature)) + # Check that the brief description is not empty + if not brief: + logger.warning("{}:{} has no brief description".format(group, name)) + # Check that the group has a description + if group not in group_names_descriptions: + logger.error("{} has no group description (referenced from {})".format(group, name)) + + desc = re.sub(r'^(\\n)*(.*?)(\\n)*$', r'\2', desc) + return desc.strip(), brief, ';'.join(params), group + + +def sort_functions(item): + group = item['group'] + name = item['name'] + + precedence = 5 + if name.startswith('_desc_'): + precedence = 0 + elif group == 'other': + if re.match(r'^pico_add_.*_output$', name): + precedence = 1 + elif name == 'pico_add_extra_outputs': + precedence = 2 + elif re.match(r'^pico_.*_binary$', name): + precedence = 3 + return group + str(precedence) + name + + +# Scan all CMakeLists.txt and .cmake files in the specific path, recursively. + +for dirpath, dirnames, filenames in os.walk(scandir): + for filename in filenames: + if filename in skip_files: + continue + # Default group is the directory name - can be overridden by the \ingroup\ command + group = os.path.basename(dirpath) + if group in skip_groups: + continue + if group in ['tools', 'cmake']: + group = 'other' + file_ext = os.path.splitext(filename)[1] + if filename == 'CMakeLists.txt' or file_ext == '.cmake': + file_path = os.path.join(dirpath, filename) + + with open(file_path, encoding="ISO-8859-1") as fh: + text = fh.read() + for match in CMAKE_FUNCTION_RE.finditer(text): + name = match.group(4) + signature = match.group(1).strip() + if signature.startswith(name): + description, brief, params, processed_group = process_commands(match.group(2).replace('#', ''), name, group, signature) + new_dict = { + 'name': name, + 'group': processed_group, + 'signature': signature, + 'brief': brief, + 'description': description, + 'params': params + } + if all_functions.get(name): + if new_dict != all_functions[name]: + logger.warning("{}:{} has multiple different definitions - using the new one from {}".format(processed_group, name, file_path)) + all_functions[name] = new_dict + + for match in CMAKE_PICO_FUNCTIONS_RE.finditer(text): + name = match.group(1) + if name not in all_functions and name not in allowed_missing_functions: + logger.warning("{} function has no description in {}".format(name, file_path)) + + +with open(outfile, 'w', newline='') as csvfile: + fieldnames = ('name', 'group', 'signature', 'brief', 'description', 'params') + writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore', dialect='excel-tab') + + writer.writeheader() + for row in sorted(all_functions.values(), key=sort_functions): + writer.writerow(row)