From 4483724df8ffc64d915bf1a991e68ca71d9ede1d Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Mon, 4 Feb 2019 15:07:02 +0800 Subject: [PATCH 1/3] ulp: use cmake function to embed ulp binaries --- components/ulp/component_ulp_common.cmake | 73 +++++------------------ components/ulp/project_include.cmake | 67 +++++++++++++++++++++ components/ulp/test/CMakeLists.txt | 9 ++- 3 files changed, 85 insertions(+), 64 deletions(-) create mode 100644 components/ulp/project_include.cmake diff --git a/components/ulp/component_ulp_common.cmake b/components/ulp/component_ulp_common.cmake index 0d2ec262ab..ce207f802f 100644 --- a/components/ulp/component_ulp_common.cmake +++ b/components/ulp/component_ulp_common.cmake @@ -1,63 +1,18 @@ -if(NOT CMAKE_BUILD_EARLY_EXPANSION) - spaces2list(ULP_S_SOURCES) - foreach(ulp_s_source ${ULP_S_SOURCES}) - get_filename_component(ulp_s_source ${ulp_s_source} ABSOLUTE) - list(APPEND ulp_s_sources ${ulp_s_source}) - endforeach() +message(WARNING "Embedding ULP binary by including \ +${IDF_PATH}/components/ulp/component_ulp_common.cmake is deprecated. Use `ulp_embed_binary` instead. \ +See API Guide for more details.") - foreach(ulp_s_source ${ulp_s_sources}) - get_filename_component(ulp_ps_source ${ulp_s_source} NAME_WE) - set(ulp_ps_output ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/${ulp_ps_source}.ulp.S) - list(APPEND ulp_ps_sources ${ulp_ps_output}) - endforeach() +spaces2list(ULP_S_SOURCES) +spaces2list(ULP_EXP_DEP_SRCS) - set(ulp_artifacts_prefix ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/${ULP_APP_NAME}) +foreach(ulp_s_source ${ULP_S_SOURCES}) + get_filename_component(ulp_src ${ulp_s_source} ABSOLUTE BASE_DIR ${COMPONENT_DIR}) + list(APPEND ulp_srcs ${ulp_src}) +endforeach() - set(ulp_artifacts ${ulp_artifacts_prefix}.bin - ${ulp_artifacts_prefix}.ld - ${ulp_artifacts_prefix}.h) +foreach(ulp_exp_dep_src ${ULP_EXP_DEP_SRCS}) + get_filename_component(ulp_dep_src ${ulp_exp_dep_src} ABSOLUTE BASE_DIR ${COMPONENT_DIR}) + list(APPEND ulp_dep_srcs ${ulp_dep_src}) +endforeach() - set(ulp_artifacts_extras ${ulp_artifacts_prefix}.map - ${ulp_artifacts_prefix}.sym - ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/esp32.ulp.ld) - - # Replace the separator for the list of ULP source files that will be passed to - # the external ULP project. This is a workaround to the bug https://public.kitware.com/Bug/view.php?id=16137. - string(REPLACE ";" "|" ulp_s_sources "${ulp_s_sources}") - - idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER) - idf_build_get_property(idf_path IDF_PATH) - idf_build_get_property(python PYTHON) - externalproject_add(${ULP_APP_NAME} - SOURCE_DIR ${idf_path}/components/ulp/cmake - BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME} - INSTALL_COMMAND "" - CMAKE_ARGS -DCMAKE_GENERATOR=${CMAKE_GENERATOR} - -DCMAKE_TOOLCHAIN_FILE=${idf_path}/components/ulp/cmake/toolchain-ulp.cmake - -DULP_S_SOURCES=${ulp_s_sources} -DULP_APP_NAME=${ULP_APP_NAME} - -DCOMPONENT_DIR=${COMPONENT_DIR} - # Even though this resolves to a ';' separated list, this is fine. This must be special behavior - # for generator expressions. - -DCOMPONENT_INCLUDES=$ - -DIDF_PATH=${idf_path} - -DSDKCONFIG=${sdkconfig_header} - -DPYTHON=${python} - BUILD_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME} --target build - BUILD_BYPRODUCTS ${ulp_artifacts} ${ulp_artifacts_extras} ${ulp_ps_sources} - ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/${ULP_APP_NAME} - BUILD_ALWAYS 1 - LIST_SEPARATOR | - ) - - spaces2list(ULP_EXP_DEP_SRCS) - set_source_files_properties(${ULP_EXP_DEP_SRCS} PROPERTIES OBJECT_DEPENDS ${ulp_artifacts}) - - include_directories(${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}) - - add_custom_target(${ULP_APP_NAME}_artifacts DEPENDS ${ULP_APP_NAME}) - - add_dependencies(${COMPONENT_LIB} ${ULP_APP_NAME}_artifacts) - - target_linker_script(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/${ULP_APP_NAME}.ld) - target_add_binary_data(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}/${ULP_APP_NAME}.bin BINARY) -endif() \ No newline at end of file +ulp_embed_binary(${ULP_APP_NAME} ${ulp_srcs} ${ulp_dep_srcs}) diff --git a/components/ulp/project_include.cmake b/components/ulp/project_include.cmake new file mode 100644 index 0000000000..b5ac4c54e2 --- /dev/null +++ b/components/ulp/project_include.cmake @@ -0,0 +1,67 @@ +# ulp_embed_binary +# +# Create ULP binary and embed into the application. +function(ulp_embed_binary app_name s_sources exp_dep_srcs) + if(NOT CMAKE_BUILD_EARLY_EXPANSION) + spaces2list(s_sources) + foreach(source ${s_sources}) + get_filename_component(source ${source} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_LIST_DIR}) + list(APPEND sources ${source}) + endforeach() + + foreach(source ${sources}) + get_filename_component(ps_source ${source} NAME_WE) + set(ps_output ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${ps_source}.ulp.S) + list(APPEND ps_sources ${ps_output}) + endforeach() + + set(ulp_artifacts_prefix ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}) + + set(ulp_artifacts ${ulp_artifacts_prefix}.bin + ${ulp_artifacts_prefix}.ld + ${ulp_artifacts_prefix}.h) + + set(ulp_artifacts_extras ${ulp_artifacts_prefix}.map + ${ulp_artifacts_prefix}.sym + ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/esp32.ulp.ld) + + # Replace the separator for the list of ULP source files that will be passed to + # the external ULP project. This is a workaround to the bug https://public.kitware.com/Bug/view.php?id=16137. + string(REPLACE ";" "|" ulp_s_sources "${ulp_s_sources}") + + idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER) + idf_build_get_property(idf_path IDF_PATH) + idf_build_get_property(python PYTHON) + externalproject_add(${app_name} + SOURCE_DIR ${idf_path}/components/ulp/cmake + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${app_name} + INSTALL_COMMAND "" + CMAKE_ARGS -DCMAKE_GENERATOR=${CMAKE_GENERATOR} + -DCMAKE_TOOLCHAIN_FILE=${idf_path}/components/ulp/cmake/toolchain-ulp.cmake + -DULP_S_SOURCES=${sources} -DULP_APP_NAME=${app_name} + -DCOMPONENT_DIR=${COMPONENT_DIR} + # Even though this resolves to a ';' separated list, this is fine. This must be special behavior + # for generator expressions. + -DCOMPONENT_INCLUDES=$ + -DIDF_PATH=${idf_path} + -DSDKCONFIG=${SDKCONFIG_HEADER} + BUILD_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/${app_name} --target build + BUILD_BYPRODUCTS ${ulp_artifacts} ${ulp_artifacts_extras} ${ulp_ps_sources} + ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name} + BUILD_ALWAYS 1 + LIST_SEPARATOR | + ) + + spaces2list(exp_dep_srcs) + set_source_files_properties(${exp_dep_srcs} PROPERTIES OBJECT_DEPENDS ${ulp_artifacts}) + + include_directories(${CMAKE_CURRENT_BINARY_DIR}/${app_name}) + + add_custom_target(${app_name}_artifacts DEPENDS ${app_name}) + + add_dependencies(${COMPONENT_LIB} ${app_name}_artifacts) + + target_linker_script(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}.ld) + target_add_binary_data(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}.bin BINARY) + endif() +endfunction() \ No newline at end of file diff --git a/components/ulp/test/CMakeLists.txt b/components/ulp/test/CMakeLists.txt index 20a82c897f..296fda0148 100644 --- a/components/ulp/test/CMakeLists.txt +++ b/components/ulp/test/CMakeLists.txt @@ -5,8 +5,7 @@ set(COMPONENT_REQUIRES unity ulp soc esp_common) register_component() -set(ULP_APP_NAME ulp_test_app) -set(ULP_S_SOURCES "ulp/test_jumps.S") -set(ULP_EXP_DEP_SRCS "test_ulp_as.c") -idf_build_get_property(idf_path IDF_PATH) -include(${idf_path}/components/ulp/component_ulp_common.cmake) \ No newline at end of file +set(ulp_app_name ulp_test_app) +set(ulp_s_sources "ulp/test_jumps.S") +set(ulp_exp_dep_srcs "test_ulp_as.c") +ulp_embed_binary(${ulp_app_name} ${ulp_s_sources} ${ulp_exp_dep_srcs}) From 443850b1a89eae0226eb601ddb4aa7825bd87422 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Mon, 4 Feb 2019 15:07:10 +0800 Subject: [PATCH 2/3] example: update ulp example to use cmake function --- examples/system/ulp/main/CMakeLists.txt | 22 ++++++++++----------- examples/system/ulp_adc/main/CMakeLists.txt | 22 ++++++++++----------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/examples/system/ulp/main/CMakeLists.txt b/examples/system/ulp/main/CMakeLists.txt index 7b39598ce4..d426857dc6 100644 --- a/examples/system/ulp/main/CMakeLists.txt +++ b/examples/system/ulp/main/CMakeLists.txt @@ -6,22 +6,20 @@ set(COMPONENT_REQUIRES soc nvs_flash ulp) register_component() # -# ULP support additions to component makefile. +# ULP support additions to component CMakeLists.txt. # -# 1. ULP_APP_NAME must be unique (if multiple components use ULP) -# Default value, override if necessary: -set(ULP_APP_NAME ulp_${COMPONENT_NAME}) +# 1. The ULP app name must be unique (if multiple components use ULP). +set(ulp_app_name ulp_${COMPONENT_NAME}) # -# 2. Specify all assembly source files here. +# 2. Specify all assembly source files. # Files should be placed into a separate directory (in this case, ulp/), # which should not be added to COMPONENT_SRCS. -set(ULP_S_SOURCES "ulp/pulse_cnt.S") +set(ulp_s_sources "ulp/pulse_cnt.S") # # 3. List all the component source files which include automatically -# generated ULP export file, $(ULP_APP_NAME).h: -set(ULP_EXP_DEP_SRCS "ulp_example_main.c") +# generated ULP export file, ${ulp_app_name}.h: +set(ulp_exp_dep_srcs "ulp_example_main.c") # -# 4. Include build rules for ULP program -# End of ULP support additions to component makefile. -# -include(${IDF_PATH}/components/ulp/component_ulp_common.cmake) +# 4. Call function to build ULP binary and embed in project using the argument +# values above. +ulp_embed_binary(${ulp_app_name} ${ulp_s_sources} ${ulp_exp_dep_srcs}) diff --git a/examples/system/ulp_adc/main/CMakeLists.txt b/examples/system/ulp_adc/main/CMakeLists.txt index 9c7f456d27..5f64763179 100644 --- a/examples/system/ulp_adc/main/CMakeLists.txt +++ b/examples/system/ulp_adc/main/CMakeLists.txt @@ -6,22 +6,20 @@ set(COMPONENT_REQUIRES soc nvs_flash ulp driver) register_component() # -# ULP support additions to component makefile. +# ULP support additions to component CMakeLists.txt. # -# 1. ULP_APP_NAME must be unique (if multiple components use ULP) -# Default value, override if necessary: -set(ULP_APP_NAME ulp_${COMPONENT_NAME}) +# 1. The ULP app name must be unique (if multiple components use ULP). +set(ulp_app_name ulp_${COMPONENT_NAME}) # -# 2. Specify all assembly source files here. +# 2. Specify all assembly source files. # Files should be placed into a separate directory (in this case, ulp/), # which should not be added to COMPONENT_SRCS. -set(ULP_S_SOURCES "ulp/adc.S") +set(ulp_s_sources "ulp/adc.S") # # 3. List all the component source files which include automatically -# generated ULP export file, $(ULP_APP_NAME).h: -set(ULP_EXP_DEP_SRCS "ulp_adc_example_main.c") +# generated ULP export file, ${ulp_app_name}.h: +set(ulp_exp_dep_srcs "ulp_adc_example_main.c") # -# 4. Include build rules for ULP program -# End of ULP support additions to component makefile. -# -include(${IDF_PATH}/components/ulp/component_ulp_common.cmake) +# 4. Call function to build ULP binary and embed in project using the argument +# values above. +ulp_embed_binary(${ulp_app_name} ${ulp_s_sources} ${ulp_exp_dep_srcs}) \ No newline at end of file From 32027805d46cca9c4cf642c46bb9872a6fa53c8e Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Mon, 4 Feb 2019 15:07:15 +0800 Subject: [PATCH 3/3] docs: update instructions on how to embed ulp binaries --- docs/en/api-guides/ulp-cmake.rst | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/docs/en/api-guides/ulp-cmake.rst b/docs/en/api-guides/ulp-cmake.rst index 87ed13aa0a..eb9826597c 100644 --- a/docs/en/api-guides/ulp-cmake.rst +++ b/docs/en/api-guides/ulp-cmake.rst @@ -29,27 +29,22 @@ To compile ULP code as part of a component, the following steps must be taken: .. note: This directory should not be added to the ``COMPONENT_SRCDIRS`` environment variable. The logic behind this is that the ESP-IDF build system will compile files found in ``COMPONENT_SRCDIRS`` based on their extensions. For ``.S`` files, ``xtensa-esp32-elf-as`` assembler is used. This is not desirable for ULP assembly files, so the easiest way to achieve the distinction is by placing ULP assembly files into a separate directory. The ULP assembly source files should also **not** be added to ``COMPONENT_SRCS`` for the same reason. See the step below for how to properly add ULP assembly source files. -2. Modify component CMakeLists.txt, appending the necessary ULP CMake definitions. As an example:: +2. Call ``ulp_embed_binary`` from the component CMakeLists.txt after registration. For example:: - set(ULP_APP_NAME ulp_${COMPONENT_NAME}) - set(ULP_S_SOURCES ulp/ulp_assembly_source_file.S) - set(ULP_EXP_DEP_SRCS "ulp_c_source_file.c") - include(${IDF_PATH}/components/ulp/component_ulp_common.cmake) + ... + register_component() - Here is each line explained: + set(ulp_app_name ulp_${COMPONENT_NAME}) + set(ulp_s_sources ulp/ulp_assembly_source_file.S) + set(ulp_exp_dep_srcs "ulp_c_source_file.c") - set(ULP_APP_NAME ulp_${COMPONENT_NAME}) - Sets the name of the generated ULP application, without an extension. This name is used for build products of the ULP application: ELF file, map file, binary file, generated header file, and generated linker export file. + ulp_embed_binary(${ulp_app_name} ${ulp_s_sources} ${ulp_exp_dep_srcs}) - set(ULP_S_SOURCES "ulp/ulp_assembly_source_file_1.S ulp/ulp_assembly_source_file_2.S") - Sets list of assembly files to be passed to the ULP assembler. The list should be space-delimited and the paths can either be absolute or relative to component CMakeLists.txt. - - set(ULP_EXP_DEP_SRCS "ulp_c_source_file_1.c ulp_c_source_file_2.c") - Sets list of source files names within the component which include the generated header file. This list is needed to build the dependencies correctly and ensure that the generated header file is created before any of these files are compiled. See section below explaining the concept of generated header files for ULP applications. - The list should be space-delimited and the paths can either be absolute or relative to component CMakeLists.txt. - - include(${IDF_PATH}/components/ulp/component_ulp_common.cmake) - Includes common definitions of ULP build steps. Configures build for ULP object files, ELF file, binary file, etc using the ULP toolchain. + The first argument to ``ulp_embed_binary`` specifies the ULP binary name. The name specified here will also be used other generated artifacts + such as the ELF file, map file, header file and linker export file. The second argument specifies the ULP assembly source files. + Finally, the third argument specifies the list of component source files which include the header file to be generated. + This list is needed to build the dependencies correctly and ensure that the generated header file is created before any of these files are compiled. + See section below explaining the concept of generated header files for ULP applications. 3. Build the application as usual (e.g. `idf.py app`)