diff --git a/tools/cmake/project.cmake b/tools/cmake/project.cmake index a875f8efa9..578368a622 100644 --- a/tools/cmake/project.cmake +++ b/tools/cmake/project.cmake @@ -69,6 +69,73 @@ function(__project_get_revision var) set(${var} "${PROJECT_VER}" PARENT_SCOPE) endfunction() +function(__component_info components output) + set(components_json "") + foreach(name ${components}) + __component_get_target(target ${name}) + __component_get_property(alias ${target} COMPONENT_ALIAS) + __component_get_property(prefix ${target} __PREFIX) + __component_get_property(dir ${target} COMPONENT_DIR) + __component_get_property(type ${target} COMPONENT_TYPE) + __component_get_property(lib ${target} COMPONENT_LIB) + __component_get_property(reqs ${target} REQUIRES) + __component_get_property(include_dirs ${target} INCLUDE_DIRS) + __component_get_property(priv_reqs ${target} PRIV_REQUIRES) + __component_get_property(managed_reqs ${target} MANAGED_REQUIRES) + __component_get_property(managed_priv_reqs ${target} MANAGED_PRIV_REQUIRES) + if("${type}" STREQUAL "LIBRARY") + set(file "$") + + # The idf_component_register function is converting each source file path defined + # in SRCS into absolute one. But source files can be also added with cmake's + # target_sources and have relative paths. This is used for example in log + # component. Let's make sure all source files have absolute path. + set(sources "") + get_target_property(srcs ${lib} SOURCES) + foreach(src ${srcs}) + get_filename_component(src "${src}" ABSOLUTE BASE_DIR "${dir}") + list(APPEND sources "${src}") + endforeach() + + else() + set(file "") + set(sources "") + endif() + + make_json_list("${reqs}" reqs) + make_json_list("${priv_reqs}" priv_reqs) + make_json_list("${managed_reqs}" managed_reqs) + make_json_list("${managed_priv_reqs}" managed_priv_reqs) + make_json_list("${include_dirs}" include_dirs) + make_json_list("${sources}" sources) + + string(CONCAT component_json + " \"${name}\": {\n" + " \"alias\": \"${alias}\",\n" + " \"target\": \"${target}\",\n" + " \"prefix\": \"${prefix}\",\n" + " \"dir\": \"${dir}\",\n" + " \"type\": \"${type}\",\n" + " \"lib\": \"${lib}\",\n" + " \"reqs\": ${reqs},\n" + " \"priv_reqs\": ${priv_reqs},\n" + " \"managed_reqs\": ${managed_reqs},\n" + " \"managed_priv_reqs\": ${managed_priv_reqs},\n" + " \"file\": \"${file}\",\n" + " \"sources\": ${sources},\n" + " \"include_dirs\": ${include_dirs}\n" + " }" + ) + string(CONFIGURE "${component_json}" component_json) + if(NOT "${components_json}" STREQUAL "") + string(APPEND components_json ",\n") + endif() + string(APPEND components_json "${component_json}") + endforeach() + set(components_json "{\n ${components_json}\n }") + set(${output} "${components_json}" PARENT_SCOPE) +endfunction() + # # Output the built components to the user. Generates files for invoking idf_monitor.py # that doubles as an overview of some of the more important build properties. @@ -105,6 +172,7 @@ function(__project_info test_components) endforeach() set(PROJECT_NAME ${CMAKE_PROJECT_NAME}) + idf_build_get_property(PROJECT_VER PROJECT_VER) idf_build_get_property(PROJECT_PATH PROJECT_DIR) idf_build_get_property(BUILD_DIR BUILD_DIR) idf_build_get_property(SDKCONFIG SDKCONFIG) @@ -112,6 +180,7 @@ function(__project_info test_components) idf_build_get_property(PROJECT_EXECUTABLE EXECUTABLE) set(PROJECT_BIN ${CMAKE_PROJECT_NAME}.bin) idf_build_get_property(IDF_VER IDF_VER) + idf_build_get_property(common_component_reqs __COMPONENT_REQUIRES_COMMON) idf_build_get_property(sdkconfig_cmake SDKCONFIG_CMAKE) include(${sdkconfig_cmake}) @@ -122,8 +191,22 @@ function(__project_info test_components) idf_build_get_property(build_dir BUILD_DIR) make_json_list("${build_components};${test_components}" build_components_json) make_json_list("${build_component_paths};${test_component_paths}" build_component_paths_json) + make_json_list("${common_component_reqs}" common_component_reqs_json) + + __component_info("${build_components};${test_components}" build_component_info_json) + + # The configure_file function doesn't process generator expressions, which are needed + # e.g. to get component target library(TARGET_LINKER_FILE), so the project_description + # file is created in two steps. The first step, with configure_file, creates a temporary + # file with cmake's variables substituted and unprocessed generator expressions. The second + # step, with file(GENERATE), processes the temporary file and substitute generator expression + # into the final project_description.json file. configure_file("${idf_path}/tools/cmake/project_description.json.in" - "${build_dir}/project_description.json") + "${build_dir}/project_description.json.templ") + file(READ "${build_dir}/project_description.json.templ" project_description_json_templ) + file(REMOVE "${build_dir}/project_description.json.templ") + file(GENERATE OUTPUT "${build_dir}/project_description.json" + CONTENT "${project_description_json_templ}") # We now have the following component-related variables: # diff --git a/tools/cmake/project_description.json.in b/tools/cmake/project_description.json.in index 3cf8abbb2d..3b5f27f3c0 100644 --- a/tools/cmake/project_description.json.in +++ b/tools/cmake/project_description.json.in @@ -1,6 +1,9 @@ { + "version": "1", "project_name": "${PROJECT_NAME}", + "project_version": "${PROJECT_VER}", "project_path": "${PROJECT_PATH}", + "idf_path": "${IDF_PATH}", "build_dir": "${BUILD_DIR}", "config_file": "${SDKCONFIG}", "config_defaults": "${SDKCONFIG_DEFAULTS}", @@ -13,10 +16,13 @@ "phy_data_partition": "${CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION}", "monitor_baud" : "${CONFIG_ESPTOOLPY_MONITOR_BAUD}", "monitor_toolprefix": "${CONFIG_SDK_TOOLPREFIX}", + "c_compiler": "${CMAKE_C_COMPILER}", "config_environment" : { "COMPONENT_KCONFIGS" : "${COMPONENT_KCONFIGS}", "COMPONENT_KCONFIGS_PROJBUILD" : "${COMPONENT_KCONFIGS_PROJBUILD}" }, + "common_component_reqs": ${common_component_reqs_json}, "build_components" : ${build_components_json}, - "build_component_paths" : ${build_component_paths_json} + "build_component_paths" : ${build_component_paths_json}, + "build_component_info" : ${build_component_info_json} } diff --git a/tools/cmake/utilities.cmake b/tools/cmake/utilities.cmake index df8b514bed..b21d454a16 100644 --- a/tools/cmake/utilities.cmake +++ b/tools/cmake/utilities.cmake @@ -178,7 +178,12 @@ endfunction() # Convert a CMake list to a JSON list and store it in a variable function(make_json_list list variable) - string(REPLACE ";" "\", \"" result "[ \"${list}\" ]") + list(LENGTH list length) + if(${length}) + string(REPLACE ";" "\", \"" result "[ \"${list}\" ]") + else() + set(result "[]") + endif() set("${variable}" "${result}" PARENT_SCOPE) endfunction()