diff --git a/tools/cmake/project.cmake b/tools/cmake/project.cmake index 2c4e24821e4..c1672693885 100644 --- a/tools/cmake/project.cmake +++ b/tools/cmake/project.cmake @@ -103,6 +103,74 @@ function(paths_with_spaces_to_list variable_name) endif() 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(JOIN "\n" component_json + " \"${name}\": {" + " \"alias\": \"${alias}\"," + " \"target\": \"${target}\"," + " \"prefix\": \"${prefix}\"," + " \"dir\": \"${dir}\"," + " \"type\": \"${type}\"," + " \"lib\": \"${lib}\"," + " \"reqs\": ${reqs}," + " \"priv_reqs\": ${priv_reqs}," + " \"managed_reqs\": ${managed_reqs}," + " \"managed_priv_reqs\": ${managed_priv_reqs}," + " \"file\": \"${file}\"," + " \"sources\": ${sources}," + " \"include_dirs\": ${include_dirs}" + " }" + ) + string(CONFIGURE "${component_json}" component_json) + if(NOT "${components_json}" STREQUAL "") + string(APPEND components_json ",\n") + endif() + string(APPEND components_json "${component_json}") + endforeach() + string(PREPEND components_json "{\n") + string(APPEND 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. @@ -139,6 +207,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) @@ -146,6 +215,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}) @@ -157,8 +227,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}") # Generate component dependency graph depgraph_generate("${build_dir}/component_deps.dot") diff --git a/tools/cmake/project_description.json.in b/tools/cmake/project_description.json.in index 330c5190a9a..3a3bc2eb725 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}", @@ -15,11 +18,14 @@ "phy_data_partition": "${CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION}", "monitor_baud" : "${CONFIG_ESPTOOLPY_MONITOR_BAUD}", "monitor_toolprefix": "${_CMAKE_TOOLCHAIN_PREFIX}", + "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_info" : ${build_component_info_json}, "debug_prefix_map_gdbinit": "${debug_prefix_map_gdbinit}" }