component_get_requirements.cmake 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. # if(IN_LIST) is used, which requires CMP0057 set to NEW
  2. cmake_policy(SET CMP0057 NEW)
  3. include("${BUILD_PROPERTIES_FILE}")
  4. include("${COMPONENT_PROPERTIES_FILE}")
  5. function(idf_build_get_property var property)
  6. cmake_parse_arguments(_ "GENERATOR_EXPRESSION" "" "" ${ARGN})
  7. if(__GENERATOR_EXPRESSION)
  8. message(FATAL_ERROR "Getting build property generator expression not
  9. supported before idf_component_register().")
  10. endif()
  11. set(${var} ${${property}} PARENT_SCOPE)
  12. endfunction()
  13. idf_build_get_property(idf_path IDF_PATH)
  14. include(${idf_path}/tools/cmake/utilities.cmake)
  15. include(${idf_path}/tools/cmake/version.cmake)
  16. function(__component_get_property var component_target property)
  17. set(_property __component_${component_target}_${property})
  18. set(${var} ${${_property}} PARENT_SCOPE)
  19. endfunction()
  20. #
  21. # Given a component name or alias, get the corresponding component target.
  22. #
  23. function(__component_get_target var name_or_alias)
  24. idf_build_get_property(component_targets __COMPONENT_TARGETS)
  25. # Assume first that the paramters is an alias.
  26. string(REPLACE "::" "_" name_or_alias "${name_or_alias}")
  27. set(component_target ___${name_or_alias})
  28. if(component_target IN_LIST component_targets)
  29. set(${var} ${component_target} PARENT_SCOPE)
  30. set(target ${component_target})
  31. else() # assumption is wrong, try to look for it manually
  32. unset(target)
  33. foreach(component_target ${component_targets})
  34. __component_get_property(_component_name ${component_target} COMPONENT_NAME)
  35. if(name_or_alias STREQUAL _component_name)
  36. set(target ${component_target})
  37. break()
  38. endif()
  39. endforeach()
  40. set(${var} ${target} PARENT_SCOPE)
  41. endif()
  42. endfunction()
  43. function(idf_component_get_property var component property)
  44. __component_get_target(component_target ${component})
  45. __component_get_property(_var ${component_target} ${property})
  46. set(${var} ${_var} PARENT_SCOPE)
  47. endfunction()
  48. macro(require_idf_targets)
  49. endmacro()
  50. macro(idf_component_mock)
  51. idf_component_register(REQUIRES cmock)
  52. return()
  53. endmacro()
  54. macro(idf_component_register)
  55. set(options)
  56. set(single_value KCONFIG KCONFIG_PROJBUILD)
  57. set(multi_value SRCS SRC_DIRS EXCLUDE_SRCS
  58. INCLUDE_DIRS PRIV_INCLUDE_DIRS LDFRAGMENTS REQUIRES
  59. PRIV_REQUIRES REQUIRED_IDF_TARGETS EMBED_FILES EMBED_TXTFILES)
  60. cmake_parse_arguments(_ "${options}" "${single_value}" "${multi_value}" "${ARGN}")
  61. set(__component_priv_requires "${__PRIV_REQUIRES}")
  62. set(__component_requires "${__REQUIRES}")
  63. set(__component_kconfig "${__KCONFIG}")
  64. set(__component_kconfig_projbuild "${__KCONFIG_PROJBUILD}")
  65. set(__component_registered 1)
  66. return()
  67. endmacro()
  68. macro(register_component)
  69. set(__component_requires "${COMPONENT_REQUIRES}")
  70. set(__component_priv_requires "${COMPONENT_PRIV_REQUIRES}")
  71. set(__component_registered 1)
  72. return()
  73. endmacro()
  74. macro(register_config_only_component)
  75. register_component()
  76. endmacro()
  77. idf_build_get_property(__common_reqs __COMPONENT_REQUIRES_COMMON)
  78. idf_build_get_property(__component_targets __COMPONENT_TARGETS)
  79. function(__component_get_requirements)
  80. # This is in a function (separate variable context) so that variables declared
  81. # and set by the included CMakeLists.txt does not bleed into the next inclusion.
  82. # We are only interested in the public and private requirements of components
  83. __component_get_property(__component_dir ${__component_target} COMPONENT_DIR)
  84. __component_get_property(__component_name ${__component_target} COMPONENT_NAME)
  85. set(COMPONENT_NAME ${__component_name})
  86. set(COMPONENT_DIR ${__component_dir})
  87. set(COMPONENT_PATH ${__component_dir}) # for backward compatibility only, COMPONENT_DIR is preferred
  88. include(${__component_dir}/CMakeLists.txt OPTIONAL)
  89. spaces2list(__component_requires)
  90. spaces2list(__component_priv_requires)
  91. set(__component_requires "${__component_requires}" PARENT_SCOPE)
  92. set(__component_priv_requires "${__component_priv_requires}" PARENT_SCOPE)
  93. set(__component_kconfig "${__component_kconfig}" PARENT_SCOPE)
  94. set(__component_kconfig_projbuild "${__component_kconfig_projbuild}" PARENT_SCOPE)
  95. set(__component_registered ${__component_registered} PARENT_SCOPE)
  96. endfunction()
  97. set(CMAKE_BUILD_EARLY_EXPANSION 1)
  98. foreach(__component_target ${__component_targets})
  99. set(__component_requires "")
  100. set(__component_priv_requires "")
  101. set(__component_registered 0)
  102. __component_get_requirements()
  103. list(APPEND __component_requires "${__common_reqs}")
  104. # Remove duplicates and the component itself from its requirements
  105. __component_get_property(__component_alias ${__component_target} COMPONENT_ALIAS)
  106. __component_get_property(__component_name ${__component_target} COMPONENT_NAME)
  107. # Prevent component from linking to itself.
  108. if(__component_requires)
  109. list(REMOVE_DUPLICATES __component_requires)
  110. list(REMOVE_ITEM __component_requires ${__component_alias} ${__component_name})
  111. endif()
  112. if(__component_priv_requires)
  113. list(REMOVE_DUPLICATES __component_priv_requires)
  114. list(REMOVE_ITEM __component_priv_requires ${__component_alias} ${__component_name})
  115. endif()
  116. set(__contents
  117. "__component_set_property(${__component_target} REQUIRES \"${__component_requires}\")
  118. __component_set_property(${__component_target} PRIV_REQUIRES \"${__component_priv_requires}\")
  119. __component_set_property(${__component_target} __COMPONENT_REGISTERED ${__component_registered})"
  120. )
  121. if(__component_kconfig)
  122. get_filename_component(__component_kconfig "${__component_kconfig}" ABSOLUTE)
  123. set(__contents
  124. "${__contents}\n__component_set_property(${__component_target} KCONFIG \"${__component_kconfig}\")"
  125. )
  126. endif()
  127. if(__component_kconfig_projbuild)
  128. get_filename_component(__component_kconfig "${__component_kconfig}" ABSOLUTE)
  129. set(__contents
  130. "${__contents}\n__component_set_property(${__component_target} KCONFIG_PROJBUILD \"${__component_kconfig_projbuild}\")"
  131. )
  132. endif()
  133. set(__component_requires_contents "${__component_requires_contents}\n${__contents}")
  134. endforeach()
  135. file(WRITE ${COMPONENT_REQUIRES_FILE} "${__component_requires_contents}")