feat(ulp): build legacy ULP APIs through CMake v2 shim

This commit is contained in:
Renz Bagaporo
2026-07-29 13:08:22 +09:00
parent 82b28b2641
commit 288b9a6e00
21 changed files with 465 additions and 46 deletions
+119 -15
View File
@@ -6,8 +6,88 @@ endif()
#
# Create ULP binary and embed into the application.
# Generate a minimal CMake v2 ULP project in the parent build directory for
# legacy ulp_embed_binary() callers. This lets the v2 ULP component graph build
# legacy source lists without writing into the application source tree.
function(__ulp_write_legacy_project project_dir sources component_dir)
set(template_dir "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/cmake/legacy_project")
set(main_dir "${project_dir}/main")
file(MAKE_DIRECTORY "${main_dir}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${template_dir}/CMakeLists.txt.in"
"${template_dir}/main/CMakeLists.txt.in"
"${template_dir}/main/ulp_legacy_inputs.cmake.in")
file(GENERATE OUTPUT "${project_dir}/CMakeLists.txt"
INPUT "${template_dir}/CMakeLists.txt.in")
file(GENERATE OUTPUT "${main_dir}/CMakeLists.txt"
INPUT "${template_dir}/main/CMakeLists.txt.in")
set(ULP_LEGACY_SOURCES)
foreach(source IN LISTS sources)
string(APPEND ULP_LEGACY_SOURCES " [=[${source}]=]\n")
endforeach()
set(ULP_LEGACY_INCLUDE_DIR_CANDIDATES)
if(DEFINED COMPONENT_NAME)
set(legacy_include_components "${COMPONENT_NAME}")
foreach(require_property IN ITEMS REQUIRES PRIV_REQUIRES)
idf_component_get_property(component_requires "${COMPONENT_NAME}" ${require_property})
list(APPEND legacy_include_components ${component_requires})
endforeach()
list(REMOVE_DUPLICATES legacy_include_components)
foreach(component IN LISTS legacy_include_components)
if(component STREQUAL "ulp")
continue()
endif()
idf_component_get_property(include_component_dir "${component}" COMPONENT_DIR)
set(include_properties INCLUDE_DIRS)
if(component STREQUAL COMPONENT_NAME)
list(APPEND include_properties PRIV_INCLUDE_DIRS)
endif()
foreach(include_property IN LISTS include_properties)
idf_component_get_property(component_includes "${component}" ${include_property})
foreach(include IN LISTS component_includes)
if(IS_ABSOLUTE "${include}")
string(APPEND ULP_LEGACY_INCLUDE_DIR_CANDIDATES " [=[${include}]=]\n")
elseif(include_component_dir)
string(APPEND ULP_LEGACY_INCLUDE_DIR_CANDIDATES
" [=[${include_component_dir}/${include}]=]\n")
endif()
endforeach()
endforeach()
endforeach()
endif()
if(component_dir)
string(APPEND ULP_LEGACY_INCLUDE_DIR_CANDIDATES " [=[${component_dir}]=]\n")
endif()
set(ULP_LEGACY_PARENT_SDKCONFIG_HEADER)
if(SDKCONFIG_HEADER AND EXISTS "${SDKCONFIG_HEADER}")
set(ULP_LEGACY_PARENT_SDKCONFIG_HEADER "${main_dir}/ulp_parent_sdkconfig.h")
file(STRINGS "${SDKCONFIG_HEADER}" parent_sdkconfig_lines)
set(parent_sdkconfig_content
"/* Generated from the parent project sdkconfig for legacy ULP sources. */\n")
foreach(parent_sdkconfig_line IN LISTS parent_sdkconfig_lines)
if(parent_sdkconfig_line MATCHES "^#define CONFIG_IDF_TOOLCHAIN(_[A-Z]+)?[ \t]")
continue()
endif()
string(APPEND parent_sdkconfig_content "${parent_sdkconfig_line}\n")
endforeach()
file(GENERATE OUTPUT "${ULP_LEGACY_PARENT_SDKCONFIG_HEADER}"
CONTENT "${parent_sdkconfig_content}")
endif()
file(READ "${template_dir}/main/ulp_legacy_inputs.cmake.in" inputs_template)
string(CONFIGURE "${inputs_template}" inputs_content @ONLY)
file(GENERATE OUTPUT "${main_dir}/ulp_legacy_inputs.cmake"
CONTENT "${inputs_content}")
endfunction()
function(__setup_ulp_project app_name project_path prefix prefix_append_bin_name type binary_names
s_sources exp_dep_srcs)
legacy_project s_sources exp_dep_srcs)
if(NOT CMAKE_BUILD_EARLY_EXPANSION)
set(ulp_cmake_dir "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/cmake")
@@ -131,7 +211,9 @@ function(__setup_ulp_project app_name project_path prefix prefix_append_bin_name
# subprojects). Do not warn about the ones a given child ignores.
--no-warn-unused-cli
-DIDF_DEFAULT_PROJECT_NAME=${app_name}
-DULP_APP_NAME=${app_name}
-DIDF_BUILD_V2=y
-DCMAKE_MODULE_PATH=${ulp_cmake_dir}
# Internal marker for the ULP child project component graph.
-D__ULP_BUILD=1
-DIDF_PARENT_BUILD_DIR=${build_dir}
@@ -147,21 +229,27 @@ function(__setup_ulp_project app_name project_path prefix prefix_append_bin_name
# share more of the normal IDF app toolchain response-file
# setup, but keep them under IDF_CUSTOM_TOOLCHAIN for now.
-DIDF_CUSTOM_TOOLCHAIN=1)
if(s_sources)
if(legacy_project)
set(generated_project_dir "${ulp_binary_dir}/legacy_project")
__ulp_write_legacy_project("${generated_project_dir}" "${sources}" "${COMPONENT_DIR}")
set(project_path "${generated_project_dir}")
elseif(s_sources)
list(APPEND ulp_project_args
-DULP_S_SOURCES=$<TARGET_PROPERTY:${app_name},ULP_SOURCES>)
endif()
if(DEFINED COMPONENT_TARGET AND TARGET ${COMPONENT_TARGET})
# Backward compatibility for existing ULP subprojects that
# include headers from the parent component. New full
# subprojects should declare their own component include
# directories and dependencies instead.
list(APPEND ulp_project_args
-DCOMPONENT_INCLUDES=$<TARGET_PROPERTY:${COMPONENT_TARGET},INTERFACE_INCLUDE_DIRECTORIES>)
endif()
if(COMPONENT_DIR)
list(APPEND ulp_project_args
-DCOMPONENT_DIR=${COMPONENT_DIR})
if(NOT legacy_project)
if(DEFINED COMPONENT_TARGET AND TARGET ${COMPONENT_TARGET})
# Backward compatibility for existing ULP subprojects that
# include headers from the parent component. New full
# subprojects should declare their own component include
# directories and dependencies instead.
list(APPEND ulp_project_args
-DCOMPONENT_INCLUDES=$<TARGET_PROPERTY:${COMPONENT_TARGET},INTERFACE_INCLUDE_DIRECTORIES>)
endif()
if(COMPONENT_DIR)
list(APPEND ulp_project_args
-DCOMPONENT_DIR=${COMPONENT_DIR})
endif()
endif()
else()
list(APPEND ulp_project_args
@@ -196,6 +284,22 @@ function(__setup_ulp_project app_name project_path prefix prefix_append_bin_name
BUILD_ALWAYS 1
)
if(IDF_BUILD_V2)
foreach(binary_name IN LISTS binary_names)
set(ulp_compat_dir "${CMAKE_CURRENT_BINARY_DIR}/${binary_name}")
foreach(extension IN ITEMS bin ld h map sym elf)
set(ulp_compat_artifact "${ulp_compat_dir}/${binary_name}.${extension}")
set(ulp_source_artifact "${ulp_binary_dir}/${binary_name}.${extension}")
add_custom_command(OUTPUT "${ulp_compat_artifact}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${ulp_compat_dir}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${ulp_source_artifact}" "${ulp_compat_artifact}"
DEPENDS "${ulp_source_artifact}"
VERBATIM)
endforeach()
endforeach()
endif()
# Only the CMake v1 path reads this property when passing ULP_S_SOURCES
# to the child project. Leaving it set for v2 is harmless and keeps the
# post-ExternalProject artifact wiring common. Can be dropped when
@@ -273,7 +377,7 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs)
__setup_ulp_project("${app_name}" "${ulp_cmake_dir}"
"${ULP_PREFIX}" FALSE "${ULP_TYPE}"
"${app_name}"
"${s_sources}" "${exp_dep_srcs}")
TRUE "${s_sources}" "${exp_dep_srcs}")
endfunction()
function(ulp_add_project app_name project_path)
@@ -298,5 +402,5 @@ function(ulp_add_project app_name project_path)
endif()
__setup_ulp_project("${app_name}" "${project_path}" "${ULP_PREFIX}"
"${ULP_PREFIX_APPEND_BIN_NAME}" "${ULP_TYPE}" "${ULP_BINARIES}" "" "")
"${ULP_PREFIX_APPEND_BIN_NAME}" "${ULP_TYPE}" "${ULP_BINARIES}" FALSE "" "")
endfunction()